I cannot figure out why getView() method cannot run correctly when I reuse View component

StackOverflow https://stackoverflow.com//questions/21063166

  •  26-12-2019
  •  | 
  •  

Domanda

I defined a Adapter which extends BaseAdapter when I use ListView to display something.I overrided View getView (int position, View convertView, ViewGroup parent) method to reuse View component, in the method, I also wrote if(convertView == null) {System.out.println("test");} block. There are 50 rows data in ListView and the screen only can display about 20 rows data. when I ran the application, LogCat printed less than 50 rows of "test" though I slided the screen to make sure all data are loaded.But why ? I think it should print 50 rows data. Here is the key code:

@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);
    } 
}

someone help me please, I am a newbie.... thanks

È stato utile?

Soluzione

Because convertView will be null only if there isn't a previously returned view that can be recycled (i.e. it's no longer on screen).

The views you return from an adapter's getView() can be recycled in later calls to getView(). The framework passes such recyclable views in via the convertView arg.

So your convertView == null branch only gets run enough times to fill the listview screen once and after that, when scrolling, these old views get recycled.

Altri suggerimenti

Android does not inflate a View for every item in your adapter. It reuses inflated views previously used for other items.

The pattern for binding views in a adapter is something like this:

@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;
}

In fact you normally would use a ViewHolder class. But first fix your basic adapter before reading about that.

You missing return view.

ListView recycles view. How ListView's recycling mechanism works

Use a ViewHolder pattern

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 
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top