Пользовательский ListAdapter в Android не работает должным образом, особенно при фильтрации

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

Строка списка XML имеет:

<ImageView
 android:id="@+id/image1"
 android:layout_height="fill_parent"
 android:src="@drawable/button1"
 android:visibility="invisible"/>

Как видите, по умолчанию все изображения невидимы.

В пользовательском SimpleAdapter я затем проверяю свое состояние и в зависимости от этого я устанавливаю изображение этой строки видимым:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View view = super.getView(position, convertView, parent);

if(condition == true){

   ((ImageView) view.findViewById(R.id.image1)).setVisibility(View.VISIBLE);
}

return view;

}

Итак, я делаю это так, используя 2 ImageView и 3 TextView в каждой строке. ImageView невидимы по умолчанию и становятся видимыми в зависимости от условия, как показано выше. TextVoews черные и получают другой цвет текста на основе другого условия.

Моя проблема в том, что это отлично работает для небольших списков, таких как 1-5 элементов или около того, но когда список становится длиннее, это не работает должным образом. Иногда результат просто неправильный, и когда я перезагружаю список на основе одних и тех же данных, я могу каждый раз видеть другой результат. Изображения установлены неправильно или цвета текста установлены неправильно.

Вторая проблема заключается в том, что это становится полностью и определенно неправильным, когда я применяю фильтр к адаптеру. У меня есть поле EditText, и я хочу применять фильтр при каждом изменении этого EditText, поэтому у меня есть TextChangedListener для этого EditText:

edittext1.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {}

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

        @Override
        public void afterTextChanged(Editable s) {

            adapter.getFilter().filter(s);
        }
    });

С того момента, как я установил фокус на этот EditText, весь список полностью меняется, и кажется, что форматирование на основе условий теперь не только «иногда неправильно», но теперь «совершенно без какой-либо логики».

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

Большое спасибо за вашу помощь в advane.


person homtg    schedule 19.08.2011    source источник


Ответы (3)


Представления адаптера перерабатываются, поэтому вам необходимо учитывать все пути, например:

if(condition == true){

   ((ImageView) view.findViewById(R.id.image1)).setVisibility(View.VISIBLE);
} else {
   ((ImageView) view.findViewById(R.id.image1)).setVisibility(View.INVISIBLE);
}

Таким образом, ImageView будет скрыто, когда условие ложно.

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

person dmon    schedule 19.08.2011
comment
спасибо решил проблему. я только что видел это 2 минуты назад, и здесь это подробно описано: stackoverflow.com/questions/4524322/ Вторая проблема все еще существует. Когда я применяю фильтр, все совершенно неправильно. Любой намек на это? Нужно ли каким-либо образом модифицировать пользовательский адаптер, чтобы сделать его фильтруемым? - person homtg; 20.08.2011

Для первой проблемы:

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    if(convertView == null) {
        convertView = mInflater.inflate(R.layout.my_list_row, null);

        if(condition == true)
            ((ImageView) convertView.findViewById(R.id.image1)).setVisibility(View.VISIBLE);
        else
            ((ImageView) convertView.findViewById(R.id.image1)).setVisibility(View.INVISIBLE);
    }

    return convertView; 
}

Что касается фильтра, что вы пытаетесь сделать? Возможно, вы захотите проверить inputTypes:

http://developer.android.com/reference/android/widget/TextView.html#attr_android%3ainputType

person b_yng    schedule 19.08.2011
comment
Что я хочу сделать, так это просто отфильтровать список, и это работает как фильтр, если единственное, что отфильтрованный список не соответствует условиям. Поэтому, когда я фильтрую строку списка 1 в отфильтрованном списке, есть видимое изображение, если это было так в списке до того, как я применил фильтр, похоже, что элементы условного представления не обновляются при применении фильтра. - person homtg; 20.08.2011

Итак, я, наконец, изменил тот SimpleAdapter, который у меня был, на ArrayAdapter и не использовал метод фильтра по умолчанию, а реализовал метод, который фильтрует ArrayList и устанавливает отфильтрованный ArrayList в качестве списка адаптеров. Теперь это работает. С SimpleAdapter изображения не были обновлены после фильтрации, а с отфильтрованным списком я не смог обновить представления. Работает сейчас.

person homtg    schedule 20.08.2011
comment
Рад слышать, что у вас все получилось. В общем, я стараюсь просто расширяться от BaseAdapter и накатывать все оттуда, расширение от ArrayAdapter не добавляет особой ценности, а в основном добавляет путаницы. - person dmon; 21.08.2011