Ответ 1
По-видимому, "исчезающий отбор" - по дизайну; это называется "сенсорный режим". Я прочитал этот документ и до сих пор не знаю, почему они думали, что это хорошая идея. Я предполагаю, что, поскольку Android изначально был предназначен для устройств с маленькими экранами, они ожидали, что вы заполнили экран списком, а затем, когда пользователь нажмет на элемент, перейдите в новый список на другом экране. Таким образом, пользователь не будет знать, что Android потерял отслеживание выбранного элемента.
Но это поведение довольно неприятно, если, например, вы хотите, чтобы пользователь выбирал элемент, а затем показывал информацию об этом элементе на том же экране. Если выбор исчезает, как пользователь должен знать, что он нажал (если, конечно, у пользователей есть область внимания золотых рыбок)?
Одним из возможных решений является изменение всех элементов списка на переключатели. Мне не очень нравится это решение, потому что оно отвлекает экранную недвижимость. Я бы предпочел просто использовать цвет фона, чтобы показать, какой элемент выбран. До сих пор я видел одно решение, но оно не совсем полное или общее. Итак, вот мое решение:
1. В вашем файле макета XML
Перейдите к элементу ListView и следующему атрибуту: android:choiceMode="singleChoice"
. Я не совсем уверен, что это делает (сам по себе он не позволяет пользователю ничего выбирать), но без этого атрибута код ниже не работает.
2. Определите следующий класс
Он используется для отслеживания выбранного элемента, а также позволяет моделировать передачу по ссылке в 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. Если пользователь нажимает кнопку без метки (то, что имя этой кнопки? "Enter"?), Тогда элемент станет "официально", но тогда у вас есть другая проблема, потому что если пользователь снова использует клавиши со стрелками, это будет выглядеть как и два элемента. Оставьте комментарий, если вы выясните, как сохранить "внутренний выбор" в IntHolder, синхронизированный с "выбором клавиатуры" или тем, что он вызвал. Во всяком случае, что называется?