Я потратил на это около 6 часов и не наткнулся ни на какие препятствия. Общая предпосылка заключается в том, что в элементе ListView
(независимо от того, создается ли он адаптером или добавляется в виде заголовка) есть строка , содержащая EditText
виджет и файл Button
. Все, что я хочу сделать, это иметь возможность использовать джогбол / стрелки для перемещения селектора к отдельным элементам, как обычно, но когда я перехожу к определенной строке - даже если мне нужно явно идентифицировать строку - у которой есть фокусируемый child, я хочу, чтобы этот ребенок получил фокус вместо того, чтобы указывать позицию с помощью селектора.
Я пробовал много возможностей, и пока мне не повезло.
расположение:
<ListView
android:id="@android:id/list"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
/>
Заголовок:
EditText view = new EditText(this);
listView.addHeaderView(view, null, true);
Предполагая, что в адаптере есть другие элементы, использование клавиш со стрелками будет перемещать выбор вверх / вниз в списке, как и ожидалось; но при переходе к строке заголовка он также отображается с помощью селектора, и нет возможности сосредоточиться на EditText
использовании jogball. Примечание: нажатие на EditText
значок сфокусирует его в этой точке, однако это зависит от сенсорного экрана, что не является обязательным требованием.
ListView
по-видимому, имеет два режима в этом отношении:
1. setItemsCanFocus(true)
Селектор: никогда не отображается, но EditText
может получить фокус при использовании стрелок. Алгоритм поиска по фокусу трудно предсказать, и нет визуальной обратной связи (в любых строках: есть ли дочерние элементы с фокусом или нет) о том, какой элемент выбран, и то и другое может дать пользователю неожиданный опыт.
2 setItemsCanFocus(false)
.: селектор всегда отображается в режиме без касания и EditText
никогда не может получить фокус - даже если вы нажмете на него.
Что еще хуже, вызов editTextView.requestFocus()
возвращает true, но фактически не дает фокус EditText.
То, что я представляю, в основном представляет собой гибрид 1 и 2, где вместо настройки списка, если все элементы являются фокусируемыми или нет, я хочу установить фокусируемость для одного элемента в списке, чтобы селектор плавно переходил от выбора целая строка для не фокусируемых элементов и обход дерева фокуса для элементов, которые содержат фокусируемые дочерние элементы.
Есть берущие?
descendantFocusability="afterDescendants"
ваш EditText сможет сосредоточиться внутри ListView, но тогда вы получите не селектор элемента списка во время навигации с DPad. Моя задача заключалась в том, чтобы селектор элементов списка находился во всех строках, кроме строки с EditText. Я рад, что это помогло. FWIW, мы закончили переоценку этой реализации и решили, что фокусируемый внутри ListView - это просто не идиоматический дизайн пользовательского интерфейса Android, поэтому мы отказались от этой идеи в пользу более удобного для Android подхода.Это мне помогло.
В вашем манифесте:
источник
OnItemSelectedListener
этого не меняете. Однако простое решение Иогана работает как шарм, спасибо!android:descendantFocusability
свойство плюс, Джо получил моиEditText
s внутриListView
правильного разрешения клавиатуры, проголосовал за оба.android:descendantFocusability
само по себе не помогло, и я не испытывал никакого энтузиазма в@Overriding
onItemSelected
течение всех 14EditText
секунд, с которыми мне приходилось иметь дело. :) Спасибо!Моей задачей было реализовать то,
ListView
что расширяется при нажатии. Дополнительное пространство показывает,EditText
где вы можете ввести текст. Приложение должно работать на версии 2.2+ (до версии 4.2.2 на момент написания)Я пробовал множество решений из этого поста и других, которые смог найти; тестировал их на устройствах от 2.2 до 4.2.2. Ни одно из решений не было удовлетворительным на всех устройствах 2.2+, каждое решение было связано с разными проблемами.
Я хотел поделиться своим окончательным решением:
android:descendantFocusability="afterDescendants"
setItemsCanFocus(true);
android:windowSoftInputMode="adjustResize"
Многие люди предлагают,adjustPan
ноadjustResize
дает гораздо лучший ux imho, просто проверьте это в своем случае. С участиемadjustPan
вы получите нижний Элементам списка затемняется, например. Документы предполагают, что («Обычно это менее желательно, чем изменение размера»). Также в 4.0.4 после того, как пользователь начинает печатать на виртуальной клавиатуре, экран перемещается вверх.adjustResize
есть некоторые проблемы с фокусом EditText. Решение состоит в том, чтобы применить решение rjrjr из этого потока. Это выглядит пугающе, но это не так. И это работает. Просто попробуйте.Дополнительно 5. Из-за того, что адаптер обновляется (из-за изменения размера представления), когда
EditText
фокусируется на версиях до HoneyComb, я обнаружил проблему с перевернутыми представлениями: получение представления для элемента ListView / обратный порядок на 2.2; работает на 4.0.3Если вы делаете некоторые анимации, вы можете захотеть изменить поведение
adjustPan
на предварительные сотовые версии, чтобы изменение размера не запускалось, а адаптер не обновлял представления. Вам просто нужно добавить что-то вроде этогоВсе это дает приемлемый ux на устройствах 2.2 - 4.2.2. Надеюсь, это сэкономит людям время, так как мне потребовалось как минимум несколько часов, чтобы прийти к такому выводу.
источник
Это спасло мне жизнь --->
установить эту линию
ListView.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
Затем в вашем манифесте в теге активности введите это ->
<activity android:windowSoftInputMode="adjustPan">
Ваше обычное намерение
источник
Мы пробуем это на коротком списке, который не выполняет повторную переработку представлений. Все идет нормально.
XML:
Ява:
источник
этот пост точно соответствует моим ключевым словам. У меня есть заголовок ListView с поиском EditText и кнопкой поиска.
Чтобы сфокусироваться на EditText после потери начального фокуса, я нашел только один ХАК:
Потеряли много часов, и это не настоящее решение. Надеюсь, это поможет кому-то крутому.
источник
Если список динамический и содержит фокусируемые виджеты, то правильным вариантом является использование RecyclerView вместо ListView IMO.
В обходных этом наборе
adjustPan
,FOCUS_AFTER_DESCENDANTS
или вручную помнить целенаправленную позицию, действительно только обходные пути. У них есть угловые случаи (прокрутка + проблемы с мягкой клавиатурой, изменение позиции курсора в EditText). Они не меняют того факта, что ListView массово создает / уничтожает представления во времяnotifyDataSetChanged
.С RecyclerView вы уведомляете об отдельных вставках, обновлениях и удалениях. Сфокусированное представление не воссоздается, поэтому нет проблем с потерей фокуса элементами управления формы. В качестве дополнительного бонуса RecyclerView анимирует вставку и удаление элементов списка.
Вот пример из официальных документов о том, как начать работу с
RecyclerView
: Руководство разработчика - создание списка с помощью RecyclerViewисточник
иногда, когда вы используете
android:windowSoftInputMode="stateAlwaysHidden"
в манифесте активность или xml, тогда он теряет фокус клавиатуры. Поэтому сначала проверьте это свойство в своем xml и манифесте, если оно есть, просто удалите его. После добавления этой опции в файл манифеста в побочном действииandroid:windowSoftInputMode="adjustPan"
и добавление этого свойства в список в xmlandroid:descendantFocusability="beforeDescendants"
источник
Другое простое решение - определить ваш onClickListener в методе getView (..) вашего ListAdapter.
Таким образом, ваша строка станет интерактивной, как и ваше внутреннее представление :)
источник
Самая важная часть - заставить фокус работать для ячейки списка. Особенно для списка на Google TV это важно:
setItemsCanFocus метод представления списка делает свое дело:
Моя ячейка списка xml начинается следующим образом:
nextFocusLeft / Right также важны для навигации D-Pad.
Для получения дополнительной информации ознакомьтесь с другими отличными ответами.
источник
Я только что нашел другое решение. Я считаю, что это скорее взлом, чем решение, но он работает на Android 2.3.7 и Android 4.3 (я даже тестировал этот старый добрый D-pad)
запустите свой веб-просмотр как обычно и добавьте это: (спасибо Майклу Бирману)
Во время вызова getView:
источник
Просто попробуй это
в
раздел вашего манифеста. Да, он ничего не регулирует, а это значит, что editText останется там, где он есть, когда открывается IME. Но это всего лишь небольшое неудобство, которое все же полностью решает проблему потери фокуса.
источник