开发者

android gallery custom adapter

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;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜