2016-04-22 58 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以及它應該是什麼類型?我有點困惑 –