I have a question,开发者_运维知识库 maybe a silly one, but I think it is important.
Why the parameter: convertView (View) on the
public View getView(int position, View convertView, ViewGroup parent)
is always null? android is supposed to recycle the views once they're created the first time, isn't it? or how can I do to recycle those views?
I feel like the method receives those 3 parameters, but in none of the google examples they use either of them.
Unfortunately, convertView
will always be null
, due to Android bug 3376. Gallery does not implement View recycling (at least as of Gingerbread/2.3.4).
A commenter in the bug suggests forking Gallery.java (from AOSP) and implementing it yourself, which may be the best option.
The convertView
parameter indeed will be null a few first times, when this function will be called. Then if you scroll the list / galery Android will give you the same view, which was constructed earlier using this function, and you should use it to optimally construct the new view, based on the old one.
Also, you should store the references to child view somewhere.
To better undestand that, look at this code example (taken from Android Developers):
public View getView(int position, View convertView, ViewGroup parent) {
// A ViewHolder keeps references to children views to avoid unneccessary calls
// to findViewById() on each row.
ViewHolder holder;
// When convertView is not null, we can reuse it directly, there is no need
// to reinflate it. We only inflate a new View when the convertView supplied
// by ListView is null.
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item_icon_text, null);
// Creates a ViewHolder and store references to the two children views
// we want to bind data to.
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.text);
holder.icon = (ImageView) convertView.findViewById(R.id.icon);
convertView.setTag(holder);
} else {
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
holder = (ViewHolder) convertView.getTag();
}
// Bind the data efficiently with the holder.
holder.text.setText(DATA[position]);
holder.icon.setImageBitmap((position & 1) == 1 ? mIcon1 : mIcon2);
return convertView;
}
On getView()
method normally you check if convertView
is null, and if it isn't you just rewrite the fields in the View adapting it to the data you get based on the position
instead of creating a new View (from inflation or whatever method you want).
Hope it helped, JQCorreia
getView() has a second parameter as view(convertView).This convertView is the view which is returned from previous iteration.For the first iteration it will be null and adapter will create (instance) view.When it is done with creating required layout,the view will be returned to its caller.This returned value will be available as 2nd parameter from the next iteration onwards.So one can decide to reuse previously returned view instead of recreating by looking at this parameter.Thus Android achives re-usability feature while creating multiple list items.
Since convertView will always be null you should implement your own algorithm of caching and reusing items. This is my implementation of Gallery adapter
public View getView(int position, View convertView, ViewGroup parent) {
int arrPosition = position % VIEW_CHACHE_SIZE;
ImageView imageView;
mCursor.moveToPosition(position);
if (parent.getHeight() > 0 && layoutParams.height == 0) {
layoutParams = new Gallery.LayoutParams(parent.getWidth() / VISIBLE_IMAGES_COUNT, (int) (parent.getHeight() * IMAGE_HEIGHT_COEFICIENT));
viewsList[0].setLayoutParams(layoutParams);
}
if (convertView != null) {
Log.i("GALLERY", "convert view not null");
}
// check views cache
if (viewsList[arrPosition] == null) {
imageView = new ImageView(mContext);
imageView.setPadding(3, 3, 3, 3);
viewsList[arrPosition] = imageView;
} else {
imageView = viewsList[arrPosition];
if (position == arrPosition) {
if (imageView.getDrawable().equals(imagesList.get(position))) {
return imageView;
}
}
}
// check images cache
if (imagesList.get(position) != null) {
imageView.setImageDrawable(imagesList.get(position));
} else {
byte[] photo = mCursor.getBlob(mCursor.getColumnIndex(DataProxy.PHOTO_COLUMN));
imagesList.put(position, new BitmapDrawable(BitmapFactory.decodeByteArray(photo, 0, photo.length)));
imageView.setImageDrawable(imagesList.get(position));
}
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
imageView.setLayoutParams(layoutParams);
return imageView;
}
.........................................................
private SparseArray<Drawable> imagesList = new SparseArray<Drawable>();
private ImageView[] viewsList = new ImageView[VIEW_CHACHE_SIZE];
private Gallery.LayoutParams layoutParams = new LayoutParams(0, 0);
private static final int VIEW_CHACHE_SIZE = 4;
精彩评论