最初我还没有意识到listview回收和convertview使用机制,但经过一整天的研究,我通过引用android.amberfog中的图像非常了解列表视图的机制。
当你的listview充满了一个适配器时,它基本上显示了listview可以在屏幕上显示的行数,即使你滚动列表也没有增加行数,这是android使用的技巧,这样listview工作效率更高 快,现在listview的内幕故事引用图像,你可以看到最初列表视图有7个可见项目,如果向上滚动,当项目1不再可见时,getView()将此视图(item1)传递给回收器,你可以使用
System.out.println("getview:"+position+" "+convertView);
你的内心
public View getView(final int position, View convertView, ViewGroup parent)
{
System.out.println("getview:"+position+" "+convertView);
ViewHolder holder;
View row=convertView;
if(row==null)
{
LayoutInflater inflater=((Activity)context).getLayoutInflater();
row=inflater.inflate(layoutResourceId, parent,false);
holder=new PakistaniDrama();
holder.tvDramaName=(TextView)row.findViewById(R.id.dramaName);
holder.cbCheck=(CheckBox)row.findViewById(R.id.checkBox);
row.setTag(holder);
}
else
{
holder=(PakistaniDrama)row.getTag();
}
holder.tvDramaName.setText(dramaList.get(position).getDramaName());
holder.cbCheck.setChecked(checks.get(position));
return row;
}
你会注意到你的logcat最初convertview对于所有可见行都是null,因为最初在recycleler中没有视图(item),所以你的getView()为可见项创建了每个新视图,但是当你向上滚动你的项目时1将发送给具有它状态的Recycler(例如TextView文本和我的情况,如果选中复选框,它也将与视图相关联并存储在回收器中)。现在,当您向上/向下滚动列表视图不会创建新视图时,它将使用已在您的回收器中的视图(转换视图),在您的Logcat中您将注意到convertView不为null,因为您的新项目8将使用convertview绘制,即,基本上它取得了来自回收器和inflater的item1视图而不是第8项,你可以在矿区代码中观察,如果你有一个复选框,如果你在位置0检查它(让比如item1还有一个复选框,你检查了它)所以当你向下滚动时你会看到第8项复选框已被选中,这就是为什么listview重新使用相同的视图,因为性能优化没有为你创建新的。
重要的事情
1.永远不要将listview的layout_height和fill_parent设置为wrap_content,因为getView()将强制您的适配器获取一些子项来测量要在列表视图中绘制的视图的高度,并且可能导致一些意外行为,例如返回convertview,即使列表不是 scrolled.always使用match_parent或固定宽度/高度。
2.如果您想在列表视图和问题之后使用某些布局或视图,如果我将layout_height设置为fill_parent,那么列表视图后面的视图将不会显示在屏幕上,因此最好放置 您的列表视图在布局中。例如线性布局并根据您的要求设置该布局的高度和宽度,并将列表视图的高度和宽度属性设置为布局(如果布局宽度为320,高度为280) )那么你的listview应该有相同的高度和宽度。 这将告诉getView()要呈现的视图的精确高度和宽度,并且getView()不会一次又一次地调用一些随机行,并且在滚动之前返回转换视图等其他问题也不会发生,我已经测试过了 这个我自己,除非我的listview在lineaLayout里面,它也有像重复视图调用和转换视图一样的问题,把Listview放在LinearLayout里对我来说就像魔术一样。(不知道为什么)
01-01 14:49:36.606: I/System.out(13871): getview 0 null
01-01 14:49:36.636: I/System.out(13871): getview 0 android.widget.RelativeLayout@406082c0
01-01 14:49:36.636: I/System.out(13871): getview 1 android.widget.RelativeLayout@406082c0
01-01 14:49:36.646: I/System.out(13871): getview 2 android.widget.RelativeLayout@406082c0
01-01 14:49:36.646: I/System.out(13871): getview 3 android.widget.RelativeLayout@406082c0
01-01 14:49:36.656: I/System.out(13871): getview 4 android.widget.RelativeLayout@406082c0
01-01 14:49:36.666: I/System.out(13871): getview 5 android.widget.RelativeLayout@406082c0
01-01 14:49:36.666: I/System.out(13871): getview 0 android.widget.RelativeLayout@406082c0
01-01 14:49:36.696: I/System.out(13871): getview 0 android.widget.RelativeLayout@406082c0
01-01 14:49:36.706: I/System.out(13871): getview 1 null
01-01 14:49:36.736: I/System.out(13871): getview 2 null
01-01 14:49:36.756: I/System.out(13871): getview 3 null
01-01 14:49:36.776: I/System.out(13871): getview 4 null
但现在它已经解决了,我知道,我不是很擅长解释,但是因为我整天都在理解,所以我认为像我这样的其他初学者可以得到我的经验帮助,我希望现在你们人们会有一点了解 ListView框架如何工作,因为它非常麻烦和棘手,所以初学者发现太多问题理解它