如何在不将焦点设置到其他控件的情况下移除焦点

时间:2011-05-24 23:17:41

标签: android android-layout

我喜欢我的UI直观;每个屏幕应该自然而不引人注目地引导用户进入应用程序的下一步。除此之外,我努力使事情变得混乱和混乱。

开个玩笑: - )

我有三个TableRow,每个都包含一个只读和不可聚焦的EditText控件,然后是一个右边的按钮。每个按钮启动相同的活动但具有不同的参数。用户在那里进行选择,子活动结束,用用户的选择填充相应的EditText

这是经典的级联值机制;每个选择都会缩小下一个选择的可用选项等。因此,我将禁用每个下一行的两个控件,直到当前行的EditText包含值。

我需要按照优先顺序做两件事之一:

  1. 单击按钮时,立即移除焦点而不将焦点设置为其他按钮
  2. 活动开始时将焦点设置为第一个按钮
  3. 问题在子活动返回后显现;单击的按钮保持焦点。

    Re:上面的#1 - 似乎没有removeFocus()方法或类似方法

    Re:上面的#2 - 我可以使用requestFocus()将焦点设置到下一行的按钮,并且在子活动返回后有效,但由于某种原因它在父节点中不起作用活动的onCreate()

    我需要在任一方向上保持UI一致性 - 在子活动完成后没有按钮具有焦点,或者每个按钮根据其在逻辑流程中的位置获得焦点,包括在任何方向之前的第一个(也是唯一的)活动按钮选择。

12 个答案:

答案 0 :(得分:160)

使用clearFocus()似乎对我来说似乎没有找到(在评论中看到另一个答案),但最终对我有用的是添加:

<LinearLayout 
    android:id="@+id/my_layout" 
    android:focusable="true" 
    android:focusableInTouchMode="true" ...>

到我的顶级布局视图(线性布局)。要从所有Buttons / EditTexts等中删除焦点,您只需执行

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

除非我将视图设置为可聚焦,否则请求焦点不会做任何事情。

答案 1 :(得分:70)

老问题,但是当我遇到类似问题并且认为我会分享我最终做的事情时,我遇到了它。

每次获得焦点的视图都不同,因此我使用了非常通用的视图:

View current = getCurrentFocus();
if (current != null) current.clearFocus();

答案 2 :(得分:8)

  1. 您可以使用View.clearFocus()

  2. 使用View.requestFocus()调用的onResume()

答案 3 :(得分:5)

<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();

I use this when already finished update profile info and remove all focus from EditText in my layout

====> Update: In parent layout content my EditText add line:

android:focusableInTouchMode="true"

答案 4 :(得分:5)

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属性   当设置为stateAlwaysHidden时,AndroidManifest.xml会指示   键盘来忽略此自动分配的初始焦点。

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

great reference

答案 5 :(得分:3)

如何在清单中为您的活动添加android:windowSoftInputMode="stateHidden"呢?

从聪明的人那里评论:https://stackoverflow.com/a/2059394/956975

答案 6 :(得分:2)

首先,它将100%工作........

  1. 创建onResume()方法。
  2. onResume()内找到findViewById()一次又一次关注的视图。
  3. 在此onResume()requestFocus()设置此视图。
  4. 在此onResume()clearFocus设置此视图。
  5. 进入相同布局的xml,找到您想要关注的顶视图,并设置focusable为真,focusableInTuch为真。
  6. onResume()内找到findViewById
  7. 的上方顶视图
  8. 在此onResume()requestFocus()设置此视图。
  9. 现在享受......

答案 7 :(得分:2)

我尝试禁用并启用视图的可聚焦性,它对我有用(焦点已重置):

focusedView.setFocusable(false);
focusedView.setFocusableInTouchMode(false);
focusedView.setFocusable(true);
focusedView.setFocusableInTouchMode(true);

答案 8 :(得分:1)

您可以尝试关闭主Activity的保存状态的能力(从而使其忘记了哪个控件有文本和什么有焦点)。你需要有一些其他的方法来记住你的EditText有什么,并在onResume()上重新填充它们。使用startActivityForResult()启动子活动,并在主Activity中创建一个onActivityResult()处理程序,该处理程序将正确更新EditText。通过这种方式,您可以在使用myButton.post(new Runnable(){run(){myButton.requestFocus();}})重新填充EditText的同时设置您想要聚焦onResume()的正确按钮;

View.post()方法最初用于设置焦点是因为可以在创建窗口并使事情稳定后执行runnable,从而允许焦点机制在此时正常运行。我发现,尝试在onCreate / Start / Resume()期间设置焦点通常会有问题。

请注意这是伪代码且未经过测试,但这是您可以尝试的方向。

答案 9 :(得分:0)

android:focusableInTouchMode="true"
android:focusable="true"
android:clickable="true"

将它们添加到包含EditTextView的ViewGroup中。 它可以按照我的约束布局正常工作。希望有帮助

答案 10 :(得分:0)

尝试以下操作(调用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();
    }

}

答案 11 :(得分:0)

你不需要清除焦点,只需在你想要焦点的地方添加这段代码

hello world /a title/ some words  -> match (group 3) + something else (group 1 and group 4)
hello world /a title/             -> match (group 3) + something else (group 1)
/a title/ some words              -> match (group 3) + something else (group 4)
/a title/                         -> match (group 3)
hello world some words            -> only something else (group 2)