В то время как ответ Брюса действительно решает проблему, он делает это очень жестоко, что наносит вред UX, поскольку он очистит фокус каждого представления, как только мы выполним прокрутку.
Он имеет дело с симптомом проблемы, но не решает фактическую причину.
как воспроизвести проблему:
Ваш EditTextимеет фокус, и клавиатура открыта, затем вы прокручиваете до точки EditText за пределами экрана, и он не был переработан в новый EditText, который теперь отображается.
Давайте сначалапонять, почему возникает эта проблема:
ListView повторно использует свои представления и снова использует их, как вы все знаете, но иногда ему не нужно использовать представление, которое сразу же исчезло с экрана, поэтомусохраняет его для будущего использования, и, поскольку его больше не нужно показывать, он отсоединит его, в результате чего значение view.mParent будет нулевым.однако клавиатуре нужно знать, как передать ввод, и она делает это, выбирая сфокусированное представление, или, если быть точным, EditText.
Так что проблема в том, что у нас есть EditText, у которого есть фокус, новнезапно не имеет родителя, поэтому мы получаем сообщение «параметр должен быть потомком этого представления». Имеет смысл.
При использовании прослушивателя прокрутки мы вызываем больше проблем.
Решение:
Нам нужно прослушать событие, которое сообщит нам, когда представление перешло в боковую кучу и больше не подключено, к счастью ListView выставляет этособытие.
listView.setRecyclerListener(new AbsListView.RecyclerListener() {
@Override
public void onMovedToScrapHeap(View view) {
if ( view.hasFocus()){
view.clearFocus(); //we can put it inside the second if as well, but it makes sense to do it to all scraped views
//Optional: also hide keyboard in that case
if ( view instanceof EditText) {
InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
}
});