Android-адаптер несколько getView - PullRequest
8 голосов
/ 07 июля 2010

Я читал о проблеме с getView, вызываемой несколько раз, и обо всех ответах. Однако я не могу найти решение для моей проблемы.

У меня есть список, в котором строки имеют два состояния: чтение или нет. Что ж, я хочу, чтобы элементы, видимые в первый раз, имели другой цвет, и когда я прокручиваю список, они меняют свой цвет на «состояние чтения».

Чтобы сделать это, в методе getView моего адаптера я установил поле isRead при окрашивании строки для этого элемента. Но проблема в следующем: поскольку метод getView вызывается несколько раз, поле помечается как прочитанное, а когда список отображается на экране, он выглядит так, как будто он уже прочитан.

Есть идеи, чтобы решить эту проблему?

Спасибо

Ответы [ 4 ]

14 голосов
/ 07 июля 2010

Полагаю, вы имеете в виду проблему с getView, запрашивающим одно и то же представление несколько раз.

ListView делает это, потому что ему нужно получить измерения для представлений по разным причинам (размер полосы прокрутки, макет и т. Д.)

Эту проблему обычно можно избежать, не используя свойство "wrap_content" в вашем списке просмотра.

Кроме того, использование getView для определения того, было ли представление отображено, является просто плохой идеей. ListView имеет много оптимизаций, которые связываются с порядком вызова getView для каждой строки, поэтому невозможно узнать, что произойдет, и ваше приложение начнет показывать странное поведение.

Старайтесь избегать любых взаимосвязей между представлением и данными, кроме концепции представления как отображения этих данных.

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

1 голос
/ 28 марта 2011

У меня была та же проблема, и я вообще не имел никакого отношения к "wrap_content" в макетах. Хотя это старая тема, я не мог понять, как решить проблему. Таким образом, я уменьшил его, добавив список в адаптере, который содержит уже нарисованные позиции, как показано в коде ниже. Я думаю, что это не сразу, но у меня это сработало.

public class ImageAdapter extends BaseAdapter {
    private Context mContext;
    private List<Integer> usedPositions  = new ArrayList<Integer>();

    public ImageAdapter(Context c, List<String> imageUrls) {
        mContext = c;
        ...
    }

    ...

    // create a new ImageView for each item referenced by the Adapter
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView;
        if (convertView == null) { 
            imageView = new ImageView(mContext);
            imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setPadding(8, 8, 8, 8);
        } else {
            imageView = (ImageView) convertView;
        }

        if (!usedPositions.contains(position)) {
            // Your code to fill the imageView object content
            usedPositions.add(position); // holds the used position
        }

        return imageView;
    }
}
0 голосов
/ 12 декабря 2011

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

private static List<String> usedPositions  = new ArrayList<String>();

...

@Override
public View getView(int position, View rowView, ViewGroup parent) {
    rowView = inflater.inflate(R.layout.download_listview_item, null);

    Log.d(LOG_TAG, "--> Position: " + position);

    if (!usedPositions.contains(String.valueOf(position))){
        usedPositions.add(String.valueOf(position));
        return rowView;
    }else{
        usedPositions.remove(String.valueOf(position));
    }

...

0 голосов
/ 07 июля 2010

Не так, как вы хотите, чтобы это работало.Причина, по которой getView() вызывается несколько раз, заключается в том, что операционная система может измерять строки, чтобы знать, как их расположить.Вам нужно было бы пометить его как прочитанное, когда они щелкают по нему или ставят флажок или что-то в этом роде.

...