2017-08-08 101 views
0

我正在處理一個android項目,我將一些TextViews放在一個RecyclerView中,同時我試圖將這些東西放入數組列表中作爲ViewHolder類型。在對程序進行一些測試後,我明白插入到ArrayList中的項目只是屏幕中顯示的項目。例如,如果我的屏幕適合15個文字瀏覽,並且我在回收視圖和數組列表中放置了30個文字視圖,則數組列表的大小將僅爲15,因此我無法對其餘項目進行任何更改。ArrayList中的RecyclerView項目

另外,當我向下滾動回收站視圖arraylist獲取滾動時顯示的項目的大小,但是當我滾動回頂部並嘗試更改TextViews的數量,並使它們減少程序崩潰。

我想要的是將所有已添加到回收站視圖中的項目也放在arraylist中以便可以使用它們。

回收站視圖類代碼:

public class Tab1Child1Numbers extends RecyclerView.Adapter<Tab1Child1Numbers.ViewHolder> { 

ArrayList<Integer> textFront; 
ArrayList<Integer> textBack; 
ArrayList<Integer> colors; 
Context context; 
ArrayList<ViewHolder> texts = new ArrayList<>(); 


public Tab1Child1Numbers(Context context, ArrayList<Integer> textFront, ArrayList<Integer> textBack, ArrayList<Integer> colors) { 
    super(); 
    this.context = context; 
    this.textFront = textFront; 
    this.textBack = textBack; 
    this.colors = colors; 
} 

@Override 
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { 
    View v = LayoutInflater.from(viewGroup.getContext()) 
      .inflate(R.layout.tab1_child1_numbers, viewGroup, false); 
    ViewHolder viewHolder = new ViewHolder(v); 
    return viewHolder; 
} 

@Override 
public void onBindViewHolder(final ViewHolder viewHolder, final int i) { 

    viewHolder.textFront.setText(textFront.get(i)+""); 
    viewHolder.textBack.setText(textBack.get(i)+""); 
    viewHolder.textFront.setBackgroundColor(colors.get(i)); 
    viewHolder.textBack.setBackgroundColor(colors.get(i)); 

    texts.add(viewHolder); 
    // cardsFront.add(viewHolder.imageFront); 
    // cardsBack.add(viewHolder.imgThumbnail); 

    viewHolder.setClickListener(new ItemClickListener() { 
     @Override 
     public void onClick(View view, int position, boolean isLongClick) { 

      if (isLongClick) { 

      } else { 
       Deck deck = new Deck(); 
       deck.flipCard(texts.get(position).frame, texts.get(position).textFront, texts.get(position).textBack); 
      } 
     } 
    }); 
} 

@Override 
public int getItemCount() { 
    return textFront.size(); 
} 

public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { 

    public TextView textFront; 
    public TextView textBack; 
    public FrameLayout frame; 
    public LinearLayout layout; 

    private ItemClickListener clickListener; 

    public ViewHolder(View itemView) { 
     super(itemView); 
     textFront = (TextView) itemView.findViewById(R.id.txt1); 
     textBack = (TextView) itemView.findViewById(R.id.txt2); 
     frame = (FrameLayout) itemView.findViewById(R.id.list_frame); 

     itemView.setOnClickListener(this); 
     itemView.setOnLongClickListener(this); 
    } 

    public void setClickListener(ItemClickListener itemClickListener) { 
     this.clickListener = itemClickListener; 
    } 

    @Override 
    public void onClick(View view) { 
     clickListener.onClick(view, getPosition(), false); 
    } 

    @Override 
    public boolean onLongClick(View view) { 
     clickListener.onClick(view, getPosition(), true); 
     return true; 
    } 
} 


class Deck { 

    private void flipCard(View rootLayout, View cardFace, View cardBack) { 


     FlipAnimation flipAnimation = new FlipAnimation(cardFace, cardBack); 

     if (cardFace.getVisibility() == View.GONE) { 
      flipAnimation.reverse(); 
     } 
     rootLayout.startAnimation(flipAnimation); 
    } 

    public void flipAll(){ 

     System.out.println(texts.size()+"--------"); 
      randomize(); 
      for (int i = 0; i < texts.size(); i++) { 
       flipCard(texts.get(i).frame, texts.get(i).textFront, texts.get(i).textBack); 
      } 

    } 

    private void randomize(){ 

     for (int i=0; i<texts.size(); i++){ 

      if (texts.get(i).textFront.getVisibility() == View.GONE) { 
       texts.get(i).textFront.setText(textFront.get(i) + ""); 
       texts.get(i).textFront.setBackgroundColor(colors.get(i)); 
      } 

      else { 
       texts.get(i).textBack.setText(textBack.get(i) + ""); 
       texts.get(i).textBack.setBackgroundColor(colors.get(i)); 
      } 

     } 
    } 

} 

回答

0

它看起來就像你試圖做一些事情,你不應該。

onBindViewHolder()在系統即將向用戶顯示ViewHolder時被系統調用。因此,它最初將被調用一次在屏幕上的每個視圖,再加上一次在屏幕外的少量視圖(以便它們可以在屏幕上很好地滾動)。

但是,這意味着當用戶滾動瀏覽適配器中的數據時,它也會被重複調用。在這些情況下,傳遞給onBindViewHolder()ViewHolder可能是回收的,這意味着它可能以前用於顯示不同的數據,現在正在重新用於顯示新數據。

比方說,您的數據集中有一百萬個項目,但您的佈局設置的方式是一次只能在屏幕上顯示15個項目。系統很可能會創建約20個實例(屏幕上有15個,其中5個可用於在屏幕外重新使用)。如果用戶足夠滾動,則將使用這20個相同的ViewHolders來顯示所有一百萬個項目。他們會一直重複使用。

這就是爲什麼這條線是有問題的:

texts.add(viewHolder); 

你會清盤建立一個列表具有潛在的數以百萬計的對象進行的,有相同的20只ViewHolder在你的列表中出現多次。

考慮以不同方式存儲數據會更好,而不是試圖存儲傳遞給onBindViewHolder()ViewHolder

+0

我已經試圖找出一種方法來存儲每個textView的viewHolders,但我失敗了。你有什麼建議嗎? –

+0

通常你不需要存儲'ViewHolder's。你應該有一些支持數據(在你的情況下,三個List的textFront,textBack和顏色),並且只是更新它。也許你需要創建第四個列表。也許最好是創建一些新的對象來管理列表中每個項目的文本/顏色/等。但是,所有這些「元數據」都應該完全獨立於適配器和視圖的內部機制(適配器應該根據當前數據設置視圖)。 –

+0

是的,我明白你在說什麼,但在我想用動畫翻轉RecyclerView內的所有TextView的情況下,如果我不能引用已經添加到其中的ViewHolders,我該怎麼做? –