2017-01-12 10 views
0

私はRecycleViewを持っていますが、これはほぼ同じビューを2つ(同じ内容ですが、異なる順序で)持っています。彼らは異なるViewHoldersを持っているので、私は異なるレイアウトをinstatiateすることができますが、残りは同じです。だから私はそれが悪い習慣であるので自分自身を繰り返さないことを望む。異なるビュータイプのRecycleView

class ViewHolder extends RecyclerView.ViewHolder { 

    PostItemBinding mViewDataBinding; 

    public ViewHolder(PostItemBinding viewDataBinding) { 
     super(viewDataBinding.getRoot()); 
     mViewDataBinding = viewDataBinding; 
     mViewDataBinding.executePendingBindings(); 
    } 

    public PostItemBinding getBinding() { 
     return mViewDataBinding; 
    } 
} 

// ------------------------------------------------------------------------------------ 

class ViewHolderComments extends RecyclerView.ViewHolder { 

    PostWithCommentItemBinding mViewDataBinding; 

    public ViewHolderComments(PostWithCommentItemBinding viewDataBinding) { 
     super(viewDataBinding.getRoot()); 
     mViewDataBinding = viewDataBinding; 
     mViewDataBinding.executePendingBindings(); 
    } 

    public PostWithCommentItemBinding getBinding() { 
     return mViewDataBinding; 
    } 
} 


@Override 
public void onBindViewHolder(final RecyclerView.ViewHolder base, final int pos) { 

    if (base instanceof ViewHolder) { 

     position = hideHeader ? pos : pos - 1; 
     setUpPostView(base, position); 

    } else if (base instanceof ViewHolderComments) { 

     position = hideHeader ? pos : pos - 1; 
     setUpCommentsView(base, position); 

    } else { 

     setUpHeader(base); 
    } 
} 

最初のビューのセットアップ:

protected void setUpPostView(RecyclerView.ViewHolder base, final int position) { 

       final ViewHolder holder = (ViewHolder) base; 

       ..... the same code 
} 

2番目のビューの設定:

protected void setUpCommentsView(RecyclerView.ViewHolder base, final int position) { 

      final ViewHolderComments holder = (ViewHolderComments) base; 

      ..... the same code 
} 

私はViewHolderのすべてが同じであるキャストの最初の行がなければここに私のコードです。どのように私はそれを最適化/改善することができますか?抽象クラスの使用?

+0

あなたの必要に応じて、https://github.com/afollestad/sectioned-recyclerview –

+0

のようなものを使用すると、継承のようなOOPの基本を使用することで利益を得ることができます。fxクラス 'ViewHolderBase'を' setup(int position) 'でそれを継承する – Selvin

+0

ViewHolderとViewHolderCommentsの違いは何ですか? –

答えて

1

EDIT:あなたはこのコードを試すことができ、私はPostItemBindingPostWithCommentItemBindingは、あなただけのだけBaseHolderクラスを必要とするかもしれませんし、ViewHolderクラスを削除することができ、適切getItemViewTypeonCreateViewHolderViewDataBinding

class BaseHolder<T extends ViewDataBinding> extends ViewHolder<T> { 
    T mViewDataBinding; 

    public BaseHolder(T viewDataBinding) { 
     super(viewDataBinding.getRoot()); 
     mViewDataBinding = viewDataBinding; 
     mViewDataBinding.executePendingBindings(); 
    } 

    public T getBinding() { 
     return mViewDataBinding; 
    } 

    public void setupView(int position) { 
     // your same code 
    } 
} 

class ViewHolder extends BaseHolder<PostItemBinding> { 

    public ViewHolder(PostItemBinding viewDataBinding) { 
     super(viewDataBinding); 
    } 
} 

class ViewHolderComments extends BaseHolder<PostWithCommentItemBinding> { 

    public ViewHolderComments(PostWithCommentItemBinding viewDataBinding) { 
     super(viewDataBinding); 
    } 
} 

@Override 
public void onBindViewHolder(final RecyclerView.ViewHolder base, final int pos) { 
    if (base instanceof BaseHolder) { 
     position = hideHeader ? pos : pos - 1; 
     ((BaseHolder) base).setupView(position); 
    } else { 
     setUpHeader(base); 
    } 
} 

からの両方が拡張されていることを前提としていViewHolderCommentsクラスですが、それは残りのコードのベースです。

+0

私の問題は、他のすべてが動作しているコードの繰り返しだけです。しかし、1つのホルダーには、PostBinding型のバインディングと、PostWithCommentBinding型のバインダーがあります。だから、ViewHolder(Post用)をViewHolderComments(コメント付き投稿用)にキャストすることはできません。私は、より明確にするために、所有者を追加します。 – charbinary

+0

@ionicorn私はあなたの質問に答えるために、私の答え、plsチェックを更新しました。ここで抽象クラスを使用する必要があります。 – Minhtdh

+0

これは私が必要としていたものです。それは完全に動作します。どうもありがとうございます!!! – charbinary

0

アダプタにgetItemViewType(int position)メソッドを実装する必要があります。このような

@Override 
public int getItemViewType(int position) { 
    switch(position) { 
     case 0: 
      return POST; 
     default: 
      return COMMENT; 
    } 
} 


@Override 
public YourViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    switch (viewType) { 
     case POST: 
      //// create view holder for: R.layout.row_post; 
      break; 
     case COMMENT: 
      //// create view holder for: R.layout.row_comment; 
      break; 
    } 

    .... 
} 
+0

私はgetItemViewTypeとonCreateViewHolderメソッドを持っていますが、私はそれに問題はありません。私はちょうど最初の行のキャストのために同じ内容の2つの異なった方法を持っていることを望んでいません。私はdatabinding.PostWithCommentItemBindingがpost_itemは私の第二1 – charbinary

1

あなたが別のソースのレイアウトと同じviewholderクラスを開始し、ちょうどホルダーにフラグを追加することができ、それに対して異なるviewholderを使用する必要はありません。

class MyViewHolder { 
    public static final int TYPE_POST = 1; 
    public static final int TYPE_COMMENT = 2; 
    public int type; 
} 

戻りTYPE_POSTまたはgetItemTypeTYPE_COMMENTは、ホルダーにonCreateViewHolderに変数を設定します。 onBindViewHolderの場合は、MyViewHolderにキャストしてtypeという変数をチェックし、それによって異なるフィールドや他のものにアクセスすることができます。

親ビューホールダークラスを作成し、それを拡張する2つのサブビューホルダーを持つこともできます。この場合は型変数は必要ありませんが、代わりに継承があります。

+0

は私がより明確にするために私のホルダーを追加しました。 – charbinary

+0

のための私の最初のデザインとpost_with_commentためのXMLであるdatabinding.PostItemBindingにキャストすることはできません受け取る同じViewHolderを使用する場合 – charbinary

+0

最初からデータバインディング部分を追加する必要があります。これは明確ではないためです。 – damian

関連する問題