Android BaseAdapter导致滚动时ListView出现故障
我对一些从书中改编的BaseAdapter代码有问题。在我的应用程序中,我到处都在使用这段代码的变体,但只是在滚动一个长列表时才意识到,ListView中的项目变得混乱,并不是所有的元素都显示出来 很难描述确切的行为,但很容易看出您是否将50个项目排序并开始上下滚动Android BaseAdapter导致滚动时ListView出现故障,android,listview,Android,Listview,我对一些从书中改编的BaseAdapter代码有问题。在我的应用程序中,我到处都在使用这段代码的变体,但只是在滚动一个长列表时才意识到,ListView中的项目变得混乱,并不是所有的元素都显示出来 很难描述确切的行为,但很容易看出您是否将50个项目排序并开始上下滚动 class ContactAdapter extends BaseAdapter { ArrayList<Contact> mContacts; public ContactAdapter(Array
class ContactAdapter extends BaseAdapter {
ArrayList<Contact> mContacts;
public ContactAdapter(ArrayList<Contact> contacts) {
mContacts = contacts;
}
@Override
public int getCount() {
return mContacts.size();
}
@Override
public Object getItem(int position) {
return mContacts.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
if(convertView == null){
LayoutInflater li = getLayoutInflater();
view = li.inflate(R.layout.groups_item, null);
TextView label = (TextView)view.findViewById(R.id.groups_item_title);
label.setText(mContacts.get(position).getName());
label = (TextView)view.findViewById(R.id.groups_item_subtitle);
label.setText(mContacts.get(position).getNumber());
}
else
{
view = convertView;
}
return view;
}
}
class ContactAdapter扩展了BaseAdapter{
ArrayList McContacts;
公共联系人适配器(ArrayList联系人){
mContacts=触点;
}
@凌驾
public int getCount(){
返回mContacts.size();
}
@凌驾
公共对象getItem(int位置){
返回mContacts.get(位置);
}
@凌驾
公共长getItemId(int位置){
返回位置;
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
视图;
if(convertView==null){
LayoutInflater li=getLayoutInflater();
视图=li.充气(R.layout.groups\u项,空);
TextView标签=(TextView)view.findViewById(R.id.groups\u item\u title);
label.setText(mContacts.get(position.getName());
label=(TextView)view.findViewById(R.id.groups\u item\u subtitle);
label.setText(mContacts.get(position.getNumber());
}
其他的
{
视图=转换视图;
}
返回视图;
}
}
只有在第一次创建文本视图
小部件时,才将数据放入其中。您需要移动这四条线:
TextView label = (TextView)view.findViewById(R.id.groups_item_title);
label.setText(mContacts.get(position).getName());
label = (TextView)view.findViewById(R.id.groups_item_subtitle);
label.setText(mContacts.get(position).getNumber());
要在
if
/else
块之后和方法返回之前更新文本视图
小部件,无论是循环行还是创建新行。要进一步澄清Commonware的答案,这里有一些更多信息:
为提高效率,li.inflate操作(此处需要解析XML中的行布局并创建适当的视图对象)由if(convertView==null)语句包装,因此,同一对象的膨胀不会在每次弹出视图时反复发生
但是,getView方法的其他部分用于设置其他参数,因此不应包含在if(convertView==null){}中。。。else{}语句
在该方法的许多常见实现中,一些textView标签、ImageView或ImageButton元素需要使用findViewById以及之后的.setText或.setImageBitmap操作,由列表[position]中的值填充。
这些操作必须在通过膨胀从头创建视图和获取现有视图(如果不为null)(例如刷新时)之后进行
另一个将此解决方案应用于ListView ArrayAdapter的好例子出现在哦,我明白了。所以ListView最多只包含填充屏幕所需的视图数?@Mr.Dummessive:或多或少。它可以缓存一对,以便能够快速响应滚动请求。但是,在UI空间为10行且适配器为1000行的
ListView
中,视图的数量将远远接近10而不是1000。大概12或14岁。这就是使用convertView
进行行循环的要点,因此Android不必创建(以及以后的GC)一大堆行小部件。