Android ==> ListView останется выбранным?

У меня есть список, полный элементов, после того, как пользователи выбирают элемент, который он загорается, а затем он возвращается к норме. Есть ли способ сделать так, чтобы, когда пользователь выбирает элемент в моем ListView, он остается выбранным и подсвечивается?

Solutions Collecting From Web of "Android ==> ListView останется выбранным?"

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

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

Одним из возможных решений является изменение всех элементов списка на переключатели. Мне не очень нравится это решение, потому что оно отвлекает экранную недвижимость. Я бы предпочел просто использовать цвет фона, чтобы показать, какой элемент выбран. До сих пор я видел одно решение, но оно не совсем полное или общее. Итак, вот мое решение:

1. В вашем файле макета XML

Перейдите к элементу ListView и следующему атрибуту: android:choiceMode="singleChoice" . Я не совсем уверен, что это делает (сам по себе он не позволяет пользователю ничего выбирать), но без этого атрибута код ниже не работает.

2. Определите следующий класс

Он используется для отслеживания выбранного элемента, а также позволяет моделировать pass-by-reference в Java:

 public class IntHolder { public int value; public IntHolder() {} public IntHolder(int v) { value = v; } } 

3. Поместите следующий код где-нибудь

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

 static void setListItems(Context context, AdapterView listView, List listItems, final IntHolder selectedPosition) { setListItems(context, listView, listItems, selectedPosition, android.R.layout.simple_list_item_1, android.R.layout.simple_spinner_dropdown_item); } static void setListItems(Context context, AdapterView listView, List listItems, final IntHolder selectedPosition, int list_item_id, int dropdown_id) { listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { public void onItemClick(AdapterView<?> list, View lv, int position, long id) { selectedPosition.value = position; } }); ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(context, list_item_id, listItems) { @Override public View getView(int position, View convertView, ViewGroup parent) { View itemView = super.getView(position, convertView, parent); if (selectedPosition.value == position) itemView.setBackgroundColor(0xA0FF8000); // orange else itemView.setBackgroundColor(Color.TRANSPARENT); return itemView; } }; adapter.setDropDownViewResource(dropdown_id); listView.setAdapter(adapter); } 

Этот код выполняет две функции: привязывает элементы списка (например, List<String> ) к списку ListView и переопределяет ArrayAdapter.getView() с некоторым кодом, который изменяет фон выбранного элемента.

4. Используйте этот код, чтобы настроить свой список.

Например:

 ListView _list; IntHolder _selectedItem = new IntHolder(-1); // nothing selected at first @Override protected void onCreate(Bundle savedInstanceState) { ... _list = (ListView)findViewById(R.id.list); List<String> items = Arrays.asList("Item 1", "Item 2", "Item 3"); setListItems(this, _list, items, _selectedItem); } 

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

Предупреждение : это решение нуждается в дальнейшем развитии. Если пользователь использует клавиши со стрелками или кнопки для выбора элемента, этот элемент не будет выбран с точки зрения IntHolder. Если пользователь нажимает кнопку без метки (как называется эта кнопка?), Введите «?», Тогда элемент станет «официально», но тогда у вас есть другая проблема, потому что если пользователь снова использует клавиши со стрелками, это будет выглядеть Как и два элемента. Оставьте комментарий, если вы выясните, как сохранить «внутренний выбор» в IntHolder, синхронизированный с «выбором клавиатуры» или тем, что он вызвал. Во всяком случае, что называется?

В ListView есть атрибут listSelector:

Drawable используется для указания текущего выбранного элемента в списке.

http://developer.android.com/reference/android/widget/AbsListView.html#attr_android:listSelector


EDIT после комментария Стэна

Чтобы убедиться, что ListView остается выбранным, вы должны

① Установите атрибут choiceMode через xml или программно.

② Используйте адаптер, который использует представления, которые реализуют интерфейс CheckedTextView , например CheckedTextView (внутри simple_list_item_single_choice layout).

Файл TestActivity.java

 public class TestActivity extends Activity { private static final int SINGLE_CHOICE = android.R.layout.simple_list_item_single_choice; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.test); String[] items = {"test 1", "test 2", "test 3"}; ListAdapter adapter = new ArrayAdapter<String>(this, SINGLE_CHOICE, items); ListView list = (ListView) findViewById(R.id.testList); list.setChoiceMode(ListView.CHOICE_MODE_SINGLE); list.setAdapter(adapter); } } 

Здесь более простое решение, чем Qwertie's:

Не полагайтесь на данный механизм выбора. Сделай сам.

 View mSelectedItemView = null; //class member variable View mTouchedItemView = null; //class member variable ListView v = (ListView) getActivity().findViewById(R.id.listView); // select on click v.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapter, View clickedViewItem, int position, long id) { if (mSelectedItemView != null) selectedItemView.setBackgroundColor(Color.WHITE); clickedViewItem.setBackgroundColor(Color.YELLOW); mSelectedItemView = clickedViewItem; } }); // highlight on touch v.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (v instanceof ListView) { ListView listView = (ListView) v; // Find the child view that was touched (perform a // hit test) Rect rect = new Rect(); int childCount = listView.getChildCount(); int[] listViewCoords = new int[2]; v.getLocationOnScreen(listViewCoords); int x = (int) event.getRawX() - listViewCoords[0]; int y = (int) event.getRawY() - listViewCoords[1]; View child; for (int i = 0; i < childCount; i++) { child = listView.getChildAt(i); child.getHitRect(rect); if (rect.contains(x, y)) { View touchedView = child; if (event.getAction() == MotionEvent.ACTION_DOWN) { touchedView .setBackgroundColor(Color.RED); mTouchedItemView = touchedView; } else if (event.getAction() == MotionEvent.ACTION_UP) { mTouchedItemView .setBackgroundColor(Color.WHITE); } } } } return false; } }); 

Также этот метод касается только кликов и не будет работать, если пользователь использует клавиши со стрелками.

Отказ от ответственности: Де-подсветка после касания не работает надежно.

Кредиты для трогательной части идут на ozik.dev: Получить элемент из списка только с помощью OnTouchListener

Просто добавьте это в свой макет списка

  android:listSelector="@drawable/selector_expandable_listview" android:drawSelectorOnTop="true" 

Используйте файл Selector.XML и этот код:

  //SetOnClickListner to catch Events listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { view.setSelected(true); } }); 

Просто добавьте это в свой ListView:

 android:listSelector="@color/my_color" 

Этот ответ работает, попробуйте этот

 @Override public void onItemClick(AdapterView<?> parent, View view, int position, long arg3) { for(int a = 0; a < parent.getChildCount(); a++) { parent.getChildAt(a).setBackgroundColor(Color.TRANSPARENT); } view.setBackgroundColor(Color.GREEN); }