2017-08-08 47 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,我该怎么做? –