android gallery自定义适配器

时间:2011-04-19 15:01:08

标签: android gallery adapter

我有一个问题,也许是一个愚蠢的问题,但我认为这很重要。

为什么参数:

上的convertView(View)

public View getView(int position, View convertView, ViewGroup parent)

总是空的? android应该在第一次创建后回收视图,不是吗?或者我该如何回收这些观点?

我觉得这个方法接收了这三个参数,但在任何谷歌示例中都没有使用它们中的任何一个。

5 个答案:

答案 0 :(得分:9)

不幸的是,由于Android bug 3376convertView始终为null。 Gallery不实现View回收(至少从Gingerbread / 2.3.4开始)。

臭虫中的一位评论者建议分享Gallery.java(来自AOSP)并自行实施,这可能是最好的选择。

答案 1 :(得分:0)

当调用此函数时,convertView参数确实将首次为空。然后,如果您滚动列表/ galery,Android将为您提供相同的视图,该视图是使用此函数在前面构建的,您应该使用它以最佳方式构建基于旧视图的新视图。

此外,您应该在某处存储对子视图的引用。

为了更好地理解这一点,请查看此代码示例(取自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;
    }

答案 2 :(得分:0)

通常在getView()方法上检查convertView是否为空,如果不是,您只需重写视图中的字段,根据{{1}将其调整为您获得的数据而不是创建一个新的视图(来自通货膨胀或你想要的任何方法)。

希望它有所帮助, JQCorreia

答案 3 :(得分:0)

getView()有第二个参数作为视图(convertView)。这个convertView是从上一次迭代返回的视图。对于第一次迭代,它将为null,并且适配器将创建(实例)视图。当它完成时创建所需的布局,视图将返回给它的调用者。这个返回的值将从下一个迭代开始作为第二个参数提供。因此,可以决定重用以前返回的视图,而不是通过查看此参数来重新创建。因此,Android可以重新获得创建多个列表项时的无效功能。

答案 4 :(得分:0)

由于convertView将始终为null,因此您应该实现自己的缓存和重用项目算法。 这是我对Gallery适配器的实现

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;