Выделить ListView выбранной строки - PullRequest
37 голосов
/ 20 февраля 2011

У меня есть список альбомов (несколько сотен).Когда я касаюсь выбранного альбома, я хочу предложить пользователю выбрать воспроизведение всего альбома или переход на его дорожку ListView.Нет проблем.Однако после прикосновения к ablum в albumListView я хочу, чтобы строка оставалась выделенной, чтобы пользователь знал, на какой элемент он щелкнул, и затем может перейти к OK или PLAY.Как выделить строку в ListView?

Ответы [ 12 ]

42 голосов
/ 01 ноября 2012

Другое решение (в основном в XML)

1) установите choiceMode из ListView в singleChoice

<ListView
    android:choiceMode="singleChoice"
.../>

2) Элементы списка должны быть Проверяемый Просмотр и использование Список состояний цвета в качестве фона

Например: album_item.xml

<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
   android:background="@drawable/list_selector"
.../>

3) Состояние цвета фона (list_selector.xml) определяет цвет выделения

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/green" android:state_checked="true"/>
    <item android:drawable="@color/green" android:state_pressed="true"/>
</selector>
35 голосов
/ 20 февраля 2011

Цитируется из http://android -developers.blogspot.de / 2008/12 / touch-mode.html

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

В этом случае, если пользователь выбирает элемент вверху списка, а затем бросает список вниз, что должно произойти с выбором? Должен ли он оставаться на предмете и прокручиваться за пределы экрана? Что должно произойти, если пользователь затем решил переместить выделение с помощью трекбола? Или еще хуже, что должно произойти, если пользователь нажимает трекбол, чтобы воздействовать на текущий выбранный элемент, который больше не отображается на экране?

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

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

19 голосов
/ 20 февраля 2011

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

Вы можете использовать CHOICE_MODE_SINGLE, чтобы выразить выбор с состоянием в списке. Это будет рассматривать выбор как проверенное состояние. До тех пор, пока представление, которое возвращает ваш адаптер, реализует интерфейс Checkable, вы можете отображать выбранное состояние по своему выбору. (Установка фона в представлении элемента или иным образом. На самом деле не нужно отображать виджет флажка.) Затем можно использовать проверенные элементы метода ListView для манипулирования или определения выбора.

12 голосов
/ 14 мая 2012

Я решил эту проблему, расширив ListView и переопределив метод getView (). Я сохранил внутренний идентификатор для «выбранного» состояния и изменил фон элемента в соответствии с ним, например:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View currView = super.getView(position, convertView, parent);
StateListItem currItem = getItem(position);
if (currItem.isItemSelected) {
    currView.setBackgroundColor(Color.RED);
} else {
    currView.setBackgroundColor(Color.BLACK);
}
return currView;
}  

В моем блоге есть пример программы: http://udinic.wordpress.com/2011/07/01/selectablelistview-make-selection-work/

11 голосов
/ 23 апреля 2014

Вот мое решение Listview:

<ListView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/white"
        android:divider="@android:color/darker_gray"
        android:dividerHeight="1dp"
        android:paddingLeft="10dip"
        android:paddingRight="10dip"
        android:choiceMode="singleChoice"
        android:paddingTop="8dip" >
    </ListView>

Написать селектор для list_row как

<!-- <item android:drawable="@color/android:transparent"  android:state_selected="true" /> -->
<item android:drawable="@android:color/darker_gray" android:state_selected="true"/>
<item android:drawable="@android:color/darker_gray" android:state_activated="true"/>    
<item android:drawable="@android:color/darker_gray" android:state_pressed="true"/>
<item android:drawable="@color/android:transparent"/>

Убедитесь, что у вас есть пункт для state_activation = true

Затем добавьте этот селектор в качестве фона list_row

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="@drawable/listitem_selector"
  android:orientation="vertical" >

<TextView
    android:id="@+id/itemName"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

6 голосов
/ 25 февраля 2013

добавить android:background="?activatedBackgroundIndicator
к основному макету элемента списка, аналогичному android.R.layout.simple_list_item_activated_2.xml

5 голосов
/ 20 февраля 2011

Реализация вашего списка в режиме единого выбора: android:choiceMode=singleChoice

Так же, как по умолчанию android.R.layout.simple_list_item_single_choice использует RadioButton для обозначения выбранного выбора, вы можете реализовать пользовательское состояние выделения или подобное в макете элемента списка, чтобы реагировать на изменения выбора. Такие методы, как getCheckedItemPosition(), могут использоваться вашим приложением, чтобы определить, какой элемент пользователь выбрал в случае необходимости.

Надеюсь, что поможет!

4 голосов
/ 31 июля 2015

Я знаю, что прошло два года с тех пор, как этот вопрос был последним активным, но на тот случай, если кому-то еще это понадобится в будущем. Вот мой XML-код ListView

<ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/results"
        android:choiceMode="singleChoice"
        android:listSelector="#ffdb700b"/>

Вы хотите изменить значение android:listSelector.

3 голосов
/ 14 декабря 2012

Следующее решение может быть использовано для выделения одного или нескольких пунктов списка. Начальная точка: существует ListFragment для отображения списка MyEntity через реализацию ArrayAdapter. Цвет TextView как части макета элемента должен измениться на серый, если элемент выбран. Несколько элементов должны быть выбраны.

  1. ListFragment должен предоставлять OnItemSelectListener (элемент YourEntity), который будет вызываться в onListItemClicked ().

    public void onListItemClick(ListView l, View v, int position, long id) {
      MyEntity entity = (MyEntity) getListView().getItemAtPosition(position);
      if (entityListSelectListener != null) 
        itemSelectListener.onItemSelect(entity); }
    
  2. ArrayAdapter владеет списком ключевых полей для выбранных элементов и предоставляет методы менеджера addSelection (MyEntity) и clearAllSelections (). Переопределенный метод getView () считывает список ключевых полей и, если там находится фактическая позиция, меняет конкретный цвет TextView на серый, в противном случае - на прозрачный.

    public View getView(int position, View convertView, ViewGroup parent) {
      ...
      if (selectedEntityList.contains(entity.key)) //... highlight view field }
    
  3. В onCreate () операции-владельца должны быть реализованы слушатели для управления ArrayAdapter: вызов addSelection () и notifyDataSetChanged ().

    entityListFragment.setEntityListSelectListener(
      new EntityListFragment.OnItemSelectedListener() {
        public void onItemSelect(MyEntity entity) {
        aa.addSelection(entity);
        aa.notifyDataSetChanged(); }});
    
2 голосов
/ 31 мая 2014

У меня была такая же проблема, я решил ее, вставив следующий код в код ListView

android:choiceMode="singleChoice"
android:listSelector="#003366"

XML-файл выглядит следующим образом

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<ListView
    android:id="@+id/file_list"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:choiceMode="singleChoice"
    android:listSelector="#003366"/>

<Button
    android:id="@+id/select"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="SELECT"
    android:layout_below="@id/file_list"/>

</RelativeLayout>
...