我无法弄清楚为什么当我重用View组件时getView()方法无法正确运行

时间:2014-01-11 14:02:03

标签: android baseadapter

当我使用BaseAdapter显示某些内容时,我定义了一个扩展ListView的适配器。我重写了View getView (int position, View convertView, ViewGroup parent)方法以重用View组件,在方法中,我还写了if(convertView == null) {System.out.println("test");}阻止。 ListView中有50行数据,屏幕只能显示约20行数据。当我运行应用程序时,LogCat打印了不到50行的“测试”,虽然我滑动屏幕以确保所有数据都已加载。但为什么呢?我认为它应该打印50行数据。这是关键代码:

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    if(convertView == null) {
        convertView = inflater.inflate(resource, null);
        System.out.println(++count + "convertView == null:" + convertView);
    } 
}
有人帮助我,我是新手......谢谢

3 个答案:

答案 0 :(得分:1)

Android不会为适配器中的每个项目充气。它重复使用之前用于其他项目的夸大视图。

适配器中绑定视图的模式如下:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View view;
    if(convertView == null) {
        view = inflater.inflate(resource, null);
    } else {
        view = convertView;
    }
    // bind data to view here
    return view;
}

事实上,您通常会使用ViewHolder类。但在阅读之前先修复你的基本适配器。

答案 1 :(得分:0)

您遗失了return view

ListView回收视图。 How ListView's recycling mechanism works

使用ViewHolder模式

http://developer.android.com/training/improving-layouts/smooth-scrolling.html

@Override
public View getView(int position, View convertView, ViewGroup parent) {
  ViewHolder holder;
  if(convertView == null) {
     convertView = inflater.inflate(resource, null);
     holder = new ViewHolder();
     holder.tv = (TextView)convertView.findViewById(R.id.textView1);   
     //initialize views
     convertView.setTag(holder);  
  } else {
     holder =(ViewHolder) convertView.getTag();
  }
  // update your view here
  holder.tv.setText("hi");
  return convertView;   
}

static class ViewHolder {
  // YourViews Declaration
  TextView tv; // an example 
}

答案 2 :(得分:0)

因为convertView只有在以前没有可以回收的视图(即不再在屏幕上)时才会null

您从适配器的getView()返回的视图可以在以后调用getView()时回收。框架通过convertView arg。

传递了这些可回收​​的视图

因此,您的convertView == null分支只会运行足够的时间来填充listview屏幕一次,然后在滚动时,这些旧视图会被回收。