Заставить Listview не использовать повторно представления - PullRequest
6 голосов
/ 25 марта 2012

Я создал пользовательский Listview (без переопределения getView() метод) для каждого элемента в ListView, имеющего следующую компоновку

contactlayout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="horizontal"
  android:layout_width="match_parent"
  android:layout_height="match_parent" android:weightSum="1">
    <CheckBox android:id="@+id/checkBox1" android:text="CheckBox" android:layout_width="134dp" android:layout_height="108dp" android:focusable="false"></CheckBox>
    <LinearLayout android:id="@+id/linearLayout1" android:layout_height="match_parent" android:orientation="vertical" android:layout_width="87dp" android:layout_weight="0.84" android:weightSum="1" >
        <TextView android:text="TextView" android:layout_height="wrap_content" android:layout_width="match_parent" android:id="@+id/name" android:layout_weight="0.03"></TextView>
        <TextView android:text="TextView" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/phone"></TextView>
        <TextView android:text="TextView" android:layout_height="wrap_content" android:layout_weight="0.03" android:layout_width="match_parent" android:id="@+id/contactid" android:visibility="invisible"></TextView>
    </LinearLayout>
</LinearLayout>

Я заполняю Listview, используя SimpleCursorAdapter следующим образом ...

Cursor c = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);

        String from[] = new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,ContactsContract.CommonDataKinds.Phone.NUMBER,ContactsContract.CommonDataKinds.Phone.CONTACT_ID};
        int to[] = new int[]{R.id.name,R.id.phone,R.id.contactid};
        SimpleCursorAdapter s = new SimpleCursorAdapter(this,R.layout.contactlayout,c,from,to);
        lv.setAdapter(s);

При нажатии кнопки я читаю состояния всех флажков.Проблема в том, что, если я проверяю один CheckBox, несколько других по линии автоматически проверяются.Я знаю, что это повторное использование Views.Как мне этого избежать?В этом случае я даже не переопределяю getView() метод, поэтому мне интересно, есть ли еще способ добиться того, чего я хочу?

Ответ

Наконец-то я реализовалчто @sastraxi предложил ...

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

        final CheckBox checkBox = (CheckBox) view.findViewById(R.id.checkBox1);
        final TextView name = (TextView) view.findViewById(R.id.name);
        final TextView contactId = (TextView) view.findViewById(R.id.contactid);
        final int pos = position;
        checkBox.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                if(checkBox.isChecked())
                {
                    checkList.add(String.valueOf(pos));
                    nameList.add(name.getText().toString());
                    contactList.add(contactId.getText().toString());
                    Log.i("Chk added",String.valueOf(pos));
                }
                else
                {
                    checkList.remove(String.valueOf(pos));
                    nameList.remove(name.getText().toString());
                    contactList.remove(contactId.getText().toString());
                    Log.i("Un Chk removed",String.valueOf(pos));
                }
            }
        });

        if(checkList.contains(String.valueOf(pos)))
        {
            checkBox.setChecked(true);
        }
        else
        {
            checkBox.setChecked(false);
        }

        return view;
    }

Ответы [ 4 ]

6 голосов
/ 16 ноября 2012

другой способ заставить не использовать повторно представления, добавьте в адаптер курсора следующее:

    @Override
    public int getItemViewType(int position) {
        return position;
    }

    @Override
    public int getViewTypeCount() {
        return 500;
    }

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

3 голосов
/ 25 марта 2012

Ах, я вижу, в чем проблема.

Создайте новый класс, который расширяет SimpleCursorAdapter, скажем CheckboxSimpleCursorAdapter, и переопределяет getView следующим образом:

public View getView(int position, View convertView, ViewGroup parent) {
    View view = super.getView(position, convertView, parent);
    CheckBox checkBox = (CheckBox) view.findViewById(R.id.CheckBox1);
    checkBox.setChecked(getIsThisListPositionChecked(position));
    return view;
}

Поскольку вы не используете макет, верхний уровень которого View реализует Checkable, вам придется все делать самостоятельно.Это включает состояние очистки (в данном случае), так как реализация по умолчанию повторно использовала View, который был проверен - как вы правильно интуитивно понимали.

Редактировать: использовать этот новый код,и реализовать метод protected boolean getIsThisListPositionChecked(int position), который возвращает, проверяется или нет элемент в данный момент (или что-то подобное).Надеюсь, я достаточно ясен - вам нужно выяснить, следует ли проверять элемент в соответствии с вашей моделью, а затем установить его при создании View.

2 голосов
/ 25 марта 2012

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

1 голос
/ 31 марта 2015

Переопределите эти два метода в вашем классе Адаптера

   @Override 
public int getViewTypeCount() 
{                 
    return getCount();

}

@Override
public int getItemViewType(int position)
 {
return position;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...