Как выделить элемент ListView с помощью OnLongClickListener из пользовательского класса адаптера в Android

Вот что я хочу сделать:

В моем основном действии у меня есть ListView с настраиваемым адаптером, потому что мой элемент ListView должен содержать TextView И CheckBox. Когда я делаю долгое нажатие на элемент, я хочу использовать режим контекстного действия в панели действий и ВЫДЕЛЯТЬ выбранный элемент ListView.

Вот что я сделал:

Я следовал этому учебнику для пользовательского адаптера и этому Учебное пособие по ActionMode. Оба работают нормально. Я могу взаимодействовать с моей базой данных, лежащей в основе моего адаптера и ListView. Я должен упомянуть, что я реализовал все для ActionMode в своем собственном классе адаптера.

Вот что НЕ работает:

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


person kaolick    schedule 21.02.2013    source источник


Ответы (3)


Наконец-то мне удалось найти решение самостоятельно. Я сделал несколько разных шагов:

Шаги, связанные с кодом:

  1. Я переместил весь код, связанный с ActionMode, из класса адаптера в класс активности. До этого я активировал режим действия, используя OnLongClickListener в моем TextView в моем элементе ListView, потому что в тот момент я не знал, как сделать текст TextView доступным для ActionMode (я хочу иметь возможность удалить его, щелкнув значок в панели действий). Когда вы используете CLickListener для одного из элементов ListView, он как бы блокирует OnClickListener элемента ListView, который вы установили в своей деятельности. Не делай этого!!!

  2. Я установил OnItemLongClickListener в свой ListView в своей деятельности. Оттуда я запускаю ActionMode И сохраняю текст из TextView элемента следующим образом (itemNames — это List<String>, установленный для моего адаптера, deleteString — это атрибут класса моей активности):

    deleteString = itemNames.get(_postion);

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

Шаги, связанные с XML:

  1. Мне пришлось удалить фоновый атрибут из основного макета элемента ListView.
  2. Мне пришлось добавить следующие атрибуты в макет внешней строки: android:clickable="true" и android:longClickable="true" (может быть, longClickable уже достаточно, просто чтобы быть уверенным ;-))
  3. Мне пришлось создать собственный селектор и установить его в качестве фона для моего макета элемента ListView: android:background="@drawable/my_selector"

Таким образом я добился следующего:

  • У меня есть ListView в моей деятельности с настраиваемым макетом (TextView + CheckBox) и настраиваемым адаптером.
  • Я могу использовать OnCheckedChangeListener в CheckBox
  • Я могу активировать ActionMode, выполнив долгий щелчок по моему элементу ListView И достигнув содержимого TextView для дальнейших процессов.
  • Я получаю подсветку фона holo_blue_light по умолчанию в своем элементе ListView, когда я нажимаю на него (я использую Holo Theme Light с темной панелью действий для своего приложения)

Единственное, что мне не удалось сделать с помощью XML, — это выделить элемент ListView, пока активен ActionMode, поэтому я сделал это, выполнив это

_view.setBackgroundResource(android.R.color.holo_blue_dark);

в OnItemLongClickListener моего ListView в моем классе Activity (не забудьте перерисовать или обновить свой ListView в onDestroyActionMode(ActionMode _mode) вашего ActionMode.Callback)

Вуаля! Я надеюсь, что это может помочь некоторым из вас! У меня ушло несколько дней и МНОГО исследований.

Вот мои примеры кода для моего макета элемента ListView и моего макета селектора:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/my_selector"
    android:clickable="true"
    android:longClickable="true" >

    <CheckBox
        android:id="@+id/checkBox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="6dp" >
    </CheckBox>

    <TextView
        android:id="@+id/shoppingListItemName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_marginLeft="10dp"
        android:layout_toLeftOf="@id/checkBox"
        android:gravity="center_vertical"
        android:minHeight="?android:attr/listPreferredItemHeightSmall"
        android:textAppearance="?android:attr/textAppearanceListItemSmall"
        android:textIsSelectable="true" >
    </TextView>

</RelativeLayout>

Мой селектор:

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_pressed="true">
        <layer-list>
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="@android:color/holo_blue_light" />
                </shape>
            </item>
        </layer-list>
    </item>
    <item>
        <color android:color="#00000000" />
    </item>

</selector>
person kaolick    schedule 26.02.2013
comment
Мне нужно было только добавить android:background=@drawable/my_selector, создать selector.xml и все. Это сработало для меня, делая именно это. - person Alejandro del Río; 01.09.2013

вы можете установить android:state_activated=true в фоновом режиме, отображаемом в макете строки списка.

<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_activated="true">
    <layer-list >
        <!-- <item >
            <color android:color="#ff00aa00"/>
        </item> -->

        <item>
            <shape android:shape="rectangle">
                <solid android:color="#aa58BAED"/>
                <corners android:radius="3px"/>
            </shape>
        </item>
    </layer-list>
</item>
<item >
    <color android:color="#00000000"/>
</item>
</selector>

Но это будет работать только для Android API> API 11

person Kapil Vats    schedule 21.02.2013
comment
Пробовал, но, к сожалению, это не работает для меня. Дело в том, что мой ListView ведет себя не так, как, скажем, ListView по умолчанию для ListActivity, а это означает, что он даже не выделяется обычным щелчком мыши. Я понятия не имею, как это изменить. - person kaolick; 23.02.2013

Я столкнулся с этим вопросом, потому что столкнулся с той же проблемой, т.е. хотел выделить элементы списка при нажатии и долгом щелчке. Это работает для меня. Прослушиватель режима множественного выбора Android с пользовательским адаптером

person Meenakshi    schedule 08.10.2013
comment
Можете ли вы добавить синопсис ссылки на случай, если она исчезнет? - person Robert; 08.10.2013
comment
Добавьте android:background=?android:activatedBackgroundIndicator в родительский LinearLayout (каждого списка), чтобы создать выделенный фон при выборе. - person Meenakshi; 09.10.2013