I cannot figure out why getView() method cannot run correctly when I reuse View component
-
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
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
}