2016-04-22 13 views
0

リサイクラービューに問題があります。私はそれに展開できるいくつかのカードビューを持っています。それらのうちの1つをクリックしてスクロールした後、別のものも開かれますが、スクロールすると開くべきものが閉じられます。それは一貫性がなく、非常に混乱している、私はそれを記述する方法を知らない。ご協力ありがとうございました。Recycler View - 1つのビューが別のビューを開く

リサイクラ表示項目のレイアウト:

<android.support.v7.widget.CardView 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="wrap_content" 
android:layout_marginBottom="@dimen/card_margin_bottom" 
android:layout_marginLeft="@dimen/card_margin_sides" 
android:layout_marginRight="@dimen/card_margin_sides" 
android:layout_marginTop="@dimen/card_margin_top"> 

<LinearLayout 
    style="@style/Widget.CardContent" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"> 


    <TextView 
     android:id="@+id/headerText" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:textAppearance="@style/TextAppearance.AppCompat.Title" 
     android:textSize="@dimen/adapter_card_view_title_text_size"/> 


    <TextView 
     android:id="@+id/expandText" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="20dp" 
     android:textSize="@dimen/adapter_card_view_expand_text_size" 
     android:visibility="gone"/> 

</LinearLayout> 

アダプタ:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> { 
private String[] headerText; 
private String[] techniqueText; 

public static class ViewHolder extends RecyclerView.ViewHolder { 
    public TextView headerText; 
    public TextView expandText; 
    public CardView mCardView; 

    public ViewHolder(CardView v) { 
     super(v); 
     mCardView = v; 
     headerText = (TextView) v.findViewById(R.id.headerText); 
     expandText = (TextView) v.findViewById(R.id.expandText); 
    } 
} 

public RecyclerViewAdapter(String[] firstParam, String[] secondParam) { 
    headerText = firstParam; 
    techniqueText = secondParam; 
} 

@Override 
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    View v = LayoutInflater.from(parent.getContext()) 
      .inflate(R.layout.card_view_layout, parent, false); 

    ViewHolder vh = new ViewHolder((CardView) v,parent.getContext()); 
    return vh; 
} 

@Override 
public void onBindViewHolder(final ViewHolder holder, int position) { 
    holder.headerText.setText(headerText[position]); 
    holder.expandText.setText(techniqueText[position]); 
    holder.mCardView.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      if (holder.expandText.getVisibility() == View.GONE) { 
       holder.expandText.setVisibility(View.VISIBLE); 
      } 
      else if (holder.expandText.getVisibility() == View.VISIBLE){ 
       holder.expandText.setVisibility(View.GONE); 
      } 
     } 
    }); 
} 

@Override 
public int getItemCount() { 
    return headerText.length; 
} 

}

リサイクラーVセットアップを表示

mRecyclerView = (RecyclerView) v.findViewById(R.id.recycler_x); 
    mRecyclerView.setHasFixedSize(false); 
    mLayoutManager = new LinearLayoutManager(this.getContext()); 
    mRecyclerView.setLayoutManager(mLayoutManager); 
    mAdapter = new RecyclerViewAdapter(firstParam,secondParam); 
    mRecyclerView.setAdapter(mAdapter); 
+0

リサイクルラビューリサイクルセルです。 –

+0

ビューは再利用されるので、アダプタの 'getView'で各ビューの状態を再初期化する必要があります。 – dharms

答えて

1

ビューはリサイクルされています。ビューを開いて下にスクロールすると、そのレイアウト(開いた状態)が新しいエントリのためにリサイクルされ、開いていることも表示されます。

private final Set<Integer> mOpenIndices = new HashSet<>(); 

@Override 
public void onBindViewHolder(final ViewHolder holder, final int position) { 
    holder.headerText.setText(headerText[position]); 
    holder.expandText.setText(techniqueText[position]); 

    if (mOpenIndices.contains(position)) { 
     holder.expandText.setVisibility(View.VISIBLE); 
    } else { 
     holder.expandText.setVisibility(View.GONE); 
    } 

    holder.mCardView.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      if (holder.expandText.getVisibility() == View.GONE) { 
       holder.expandText.setVisibility(View.VISIBLE); 
       mOpenIndices.add(position); 
      } 
      else if (holder.expandText.getVisibility() == View.VISIBLE){ 
       holder.expandText.setVisibility(View.GONE); 
       mOpenIndices.remove(position); 
      } 
     } 
    }); 
} 

今、あなただけ(開/閉)ビューステートを追跡する必要があります。そうは次のようにあなたは、リサイクル時に各ビューの状態をリセットする必要があります。たとえば、開いているビューのインデックスを含む整数のセット、または好みの他のソリューションを使用できます。

+0

どこにそのセットを置くべきですか、どのタイプにする必要がありますか?私はちょっと混乱した –

+1

私は答えを更新します。 – Francesc

1

RecyclerViewの概念は、表示アイテムの数個のビューしか作成せず、スクリーンの限界を超えてリサイクルされるということです。これは、メモリとパフォーマンスの点で大きなリスト(数百または数千のアイテムを考える)に大きな違いをもたらします。

ビューはリサイクルされ、その状態を失うということが起こります。明示的に状態を保存し、onBindViewHolderに復元する必要があります。あなたは追加のArrayListのは、あなたの状態を保持するのに十分な大きサイズでexpandedと呼ばれる必要がありますことを意味し

@Override 
public void onBindViewHolder(final ViewHolder holder, int position) { 
    holder.headerText.setText(headerText[position]); 
    holder.expandText.setText(techniqueText[position]); 
    holder.expandText.setVisibility(expanded[position] ? View.VISIBLE: View.GONE); 
    holder.mCardView.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      expanded[position] = !expanded[position] 
      holder.expandText.setVisibility(expanded[position] ? View.VISIBLE: View.GONE); 
     } 
    }); 
} 

:ような何か。

+0

ArrayListをどこに置く必要がありますか?私はちょっと混乱している –

関連する問題