我对回收站视图有疑问。我有几个可以扩展的卡片视图。单击其中一个并向下滚动后,另一个打开,但当我向后滚动时,应该打开的那个被关闭。这是不一致和非常令人困惑的,我甚至不知道如何描述它。谢谢你的帮助。
Recycler查看项目布局:
<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;
}
}
Recycler View设置:
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 :(得分: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);
}
}
});
}
现在您只需要跟踪视图状态(打开/关闭)。例如,您可以使用包含开放视图索引的一组整数,或者您喜欢的其他一些解决方案。
答案 1 :(得分:1)
RecyclerView的概念是它只为可见项创建了几个视图,当它们超出屏幕限制时会被回收。这在内存和性能方面对大型列表(数百或数千个项目)产生巨大影响。
您遇到的情况是View被回收并因此失去其状态。您需要明确地存储状态并在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);
}
});
}
这意味着您需要一个名为expanded
的额外ArrayList,其大小足以保持您的状态。