Как убрать фокус, не устанавливая фокус на другой элемент управления? - PullRequest
80 голосов
/ 25 мая 2011

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

Шучу: -)

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

Это классический механизм каскадных значений; каждый выбор сужает доступные параметры для следующего выбора и т. д. Таким образом, я отключаю оба элемента управления в каждой из следующих строк, пока EditText в текущей строке не содержит значение.

Мне нужно сделать одну из двух вещей в следующем порядке:

  1. При нажатии кнопки немедленно снимите фокус, не устанавливая фокус на другую кнопку
  2. Установить фокус на первую кнопку, когда начинается действие

Проблема проявляется после возврата подэтапа; кнопка, на которую нажали, сохраняет фокус.

Re: # 1 выше - Кажется, нет removeFocus() метода или чего-то подобного

Re: # 2 выше - я могу использовать requestFocus() для установки фокуса на кнопку в следующей строке, и это работает после возврата подэтапа, но по какой-то причине он не работает в родительском действии onCreate().

Мне нужна согласованность пользовательского интерфейса в любом направлении - либо кнопки не имеют фокуса после завершения подоперации, либо каждая кнопка получает фокус в зависимости от своего места в логическом потоке, включая самую первую (и единственную) активную кнопку перед выбор.

Ответы [ 11 ]

163 голосов
/ 25 мая 2011

Использование clearFocus (), по-видимому, также не сработало для меня, как вы нашли (см. В комментариях к другому ответу), но в конечном итоге у меня сработало добавление:мой самый верхний уровень Layout View (линейный макет).Чтобы убрать фокус со всех кнопок / EditTexts и т. Д., Вы можете просто сделать

LinearLayout myLayout = (LinearLayout) activity.findViewById(R.id.my_layout);
myLayout.requestFocus();

Запрос фокуса ничего не сделал, если я не установил вид для фокусировки.

72 голосов
/ 18 марта 2013

Старый вопрос, но я столкнулся с ним, когда у меня была похожая проблема, и подумал, что поделюсь тем, что я в итоге сделал.

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

View current = getCurrentFocus();
if (current != null) current.clearFocus();
8 голосов
/ 25 мая 2011
  1. Вы можете использовать View.clearFocus().

  2. Использовать View.requestFocus() с onResume().

5 голосов
/ 08 октября 2018

android:descendantFocusability="beforeDescendants"

Использование следующего в упражнении с некоторыми опциями макета, показанными ниже, работало должным образом.

 getWindow().getDecorView().findViewById(android.R.id.content).clearFocus();

в связи со следующими параметрами в корневом представлении.

<?xml
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:descendantFocusability="beforeDescendants" />

https://developer.android.com/reference/android/view/ViewGroup#attr_android:descendantFocusability

Ответить благодаря: https://forums.xamarin.com/discussion/1856/how-to-disable-auto-focus-on-edit-text

Об windowSoftInputMode

Есть еще одна точка зрения, о которой нужно знать. По умолчанию, Android автоматически назначит начальный фокус на первый EditText или фокусируемый контроль в вашей деятельности. Естественно, что InputMethod (обычно программная клавиатура) будет реагировать на фокус событие, показывая себя. Атрибут windowSoftInputMode в AndroidManifest.xml, когда установлено значение stateAlwaysHidden, инструктирует клавиатура, чтобы игнорировать этот автоматически назначенный начальный фокус.

<activity
    android:name=".MyActivity"
    android:windowSoftInputMode="stateAlwaysHidden"/>

отличная ссылка

5 голосов
/ 02 декабря 2016
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto"
          android:id="@+id/ll_root_view"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical">

LinearLayout llRootView = findViewBindId(R.id.ll_root_view);
llRootView.clearFocus();

Я использую это, когда уже закончу обновлять информацию профиля и удаляю все фокусы из EditText в моем макете

====> Обновление: в содержимом родительского макета мой EditText добавляет строку:

android:focusableInTouchMode="true"
3 голосов
/ 12 ноября 2014

Как насчет простого добавления android:windowSoftInputMode="stateHidden" к вашей активности в манифесте.

Взято от умного человека, комментирующего это: https://stackoverflow.com/a/2059394/956975

2 голосов
/ 26 июня 2017

Я попытался отключить и включить фокусировку для просмотра, и у меня это сработало (фокус был сброшен):

focusedView.setFocusable(false);
focusedView.setFocusableInTouchMode(false);
focusedView.setFocusable(true);
focusedView.setFocusableInTouchMode(true);
2 голосов
/ 02 декабря 2014

Прежде всего, это будет работать на 100% ........

  1. Создать onResume() метод.
  2. Внутри этого onResume() найдите представление, котороефокусируется снова и снова findViewById().
  3. Внутри этого onResume() установите requestFocus() для этого вида.
  4. Внутри этого onResume() установите clearFocus для этого вида.
  5. Перейдите в xml того же макета и найдите тот вид сверху, на который вы хотите сфокусироваться, и установите focusable true и focusableInTuch true.
  6. Внутри этого onResume() найдите вышеуказанный вид сверхуfindViewById
  7. Внутри этого onResume() установите requestFocus() для этого вида в последний раз.
  8. А теперь наслаждайтесь ......
1 голос
/ 13 сентября 2011

Вы можете попробовать отключить способность основного действия, чтобы сохранить его состояние (таким образом, заставив забыть, какой элемент управления имеет текст, а какой - фокус).Вам нужно будет иметь какой-то другой способ запоминания того, что есть у вашего EditText, и повторного заселения их в onResume ().Запустите ваши дочерние действия с помощью startActivityForResult () и создайте обработчик onActivityResult () в вашем основном действии, который будет корректно обновлять EditText.Таким образом, вы можете установить правильную кнопку, на которую вы хотите сфокусироваться наResume (), в то же время, когда вы заново заполняете EditText с помощью myButton.post (new Runnable () {run () {myButton.requestFocus ();}});

Метод View.post () полезен для первоначальной установки фокуса, потому что этот runnable будет выполнен после того, как окно будет создано, и все уладится, позволяя механизму фокуса функционировать должным образом к этому времени.Я обнаружил, что при попытке установить фокус во время onCreate / Start / Resume () обычно возникают проблемы.

Обратите внимание, что это псевдокод, и он не проверен, но это возможное направление, которое вы можете попробовать.

0 голосов
/ 02 марта 2019

Попробуйте следующее (вызов clearAllEditTextFocuses();)

private final boolean clearAllEditTextFocuses() {
    View v = getCurrentFocus();
    if(v instanceof EditText) {
        final FocusedEditTextItems list = new FocusedEditTextItems();
        list.addAndClearFocus((EditText) v);

        //Focus von allen EditTexten entfernen
        boolean repeat = true;
        do {
            v = getCurrentFocus();
            if(v instanceof EditText) {
                if(list.containsView(v))
                    repeat = false;
                else list.addAndClearFocus((EditText) v);
            } else repeat = false;
        } while(repeat);

        final boolean result = !(v instanceof EditText);
        //Focus wieder setzen
        list.reset();
        return result;
    } else return false;
}

private final static class FocusedEditTextItem {

    private final boolean focusable;

    private final boolean focusableInTouchMode;

    @NonNull
    private final EditText editText;

    private FocusedEditTextItem(final @NonNull EditText v) {
        editText = v;
        focusable = v.isFocusable();
        focusableInTouchMode = v.isFocusableInTouchMode();
    }

    private final void clearFocus() {
        if(focusable)
            editText.setFocusable(false);
        if(focusableInTouchMode)
            editText.setFocusableInTouchMode(false);
        editText.clearFocus();
    }

    private final void reset() {
        if(focusable)
            editText.setFocusable(true);
        if(focusableInTouchMode)
            editText.setFocusableInTouchMode(true);
    }

}

private final static class FocusedEditTextItems extends ArrayList<FocusedEditTextItem> {

    private final void addAndClearFocus(final @NonNull EditText v) {
        final FocusedEditTextItem item = new FocusedEditTextItem(v);
        add(item);
        item.clearFocus();
    }

    private final boolean containsView(final @NonNull View v) {
        boolean result = false;
        for(FocusedEditTextItem item: this) {
            if(item.editText == v) {
                result = true;
                break;
            }
        }
        return result;
    }

    private final void reset() {
        for(FocusedEditTextItem item: this)
            item.reset();
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...