2016-04-22 63 views
0

我有一个回收站视图的问题。我有几张可以扩展的卡片视图。当我点击其中一个并向下滚动时,另一个也被打开,但是当我向后滚动时,应该打开的那个被关闭。它不一致,很混乱,我甚至不知道如何描述它。感谢您的帮助。Recycler View - 一个视图打开另一个视图

回收站查看商品布局:

<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

这是因为recyclerview回收细胞。 –

+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

我应该在哪里放置这个Set以及它应该是什么类型?林有点困惑 –

+1

我会更新答案。 – Francesc

1

RecyclerView的概念是它只为可见物品创建了几个视图,当它们超出屏幕限制时,这些视图会被回收。这对于大型列表(想象数百或数千个项目)在内存和性能方面产生巨大差异。

发生在你身上的是视图被回收并因此失去其状态。您需要明确存储状态并将其恢复到onBindViewHolder。喜欢的东西:

@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); 
     } 
    }); 
} 

这意味着,你需要一个额外的ArrayList称为expanded的大小大到足以容纳你的状态。

+0

我应该在哪里放置ArrayList以及它应该是什么类型?我有点困惑 –