пользовательский адаптер галереи Android - PullRequest
3 голосов
/ 19 апреля 2011

У меня есть вопрос, может быть, глупый, но я думаю, что это важно.

Почему параметр: convertView (View) на

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

всегда равно нулю? Android должен перерабатывать представления, как только они были созданы в первый раз, не так ли? или как я могу сделать, чтобы переработать эти представления?

Мне кажется, что метод получает эти 3 параметра, но ни в одном из примеров Google они не используют ни один из них.

Ответы [ 5 ]

9 голосов
/ 25 мая 2011

К сожалению, convertView всегда будет null из-за ошибки Android 3376 .В Gallery не реализована утилизация View (по крайней мере, в Gingerbread / 2.3.4).

Комментатор в сообщении об ошибке предлагает разложить Gallery.java (из AOSP) и реализовать его самостоятельно, что может быть лучшим вариантом.

0 голосов
/ 07 декабря 2012

Поскольку convertView всегда будет нулевым, вам следует реализовать собственный алгоритм кэширования и повторного использования элементов. Это моя реализация адаптера галереи

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 голосов
/ 04 июня 2012

getView () имеет второй параметр как view (convertView). Это convertView - это представление, возвращаемое из предыдущей итерации. Для первой итерации оно будет нулевым, и адаптер создаст (экземпляр) представление. Когда это делается с помощьюсоздавая требуемый макет, представление будет возвращено вызывающей стороне. Это возвращаемое значение будет доступно в качестве второго параметра начиная со следующей итерации и далее. Таким образом, можно решить повторно использовать ранее возвращенное представление вместо воссоздания, посмотрев на этот параметр. Таким образом, Android достигаетвозможность использования при создании нескольких элементов списка.

0 голосов
/ 19 апреля 2011

При getView() методе обычно вы проверяете, является ли convertView нулевым, а если нет, просто переписываете поля в представлении, адаптируя его к данным, полученным на основе position, вместо создания новогоПросмотр (от инфляции или любого другого метода, который вы хотите).

Надеюсь, это помогло, JQCorreia

0 голосов
/ 19 апреля 2011

Параметр convertView действительно несколько раз будет нулевым, когда эта функция будет вызвана.Затем, если вы прокрутите список / галерею, Android выдаст вам то же представление, которое было построено ранее с использованием этой функции, и вы должны использовать его для оптимального построения нового представления на основе старого.

ТакжеВы должны где-то хранить ссылки на дочерний вид.

Чтобы лучше понять это, посмотрите на этот пример кода (взят из Разработчики Android ):

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