android - 如何清除 View 中所有可选元素的焦点?

标签 android focus navigation-drawer android-view

我的问题很简单。如何清除 View 中可能具有焦点的所有元素的焦点( EditText - 或 - TextView textIsSelectable="true" 并且文本在 clearFocus 事件发生时被选中)。

为什么要问(如果我没有得到上面的一般回复):

我有几个 fragment 可以通过导航 View 访问。我的主要目标是在导航 View 中在抽屉打开时失去对 fragment 中元素的关注。我知道可以为 NavigationDrawer 获取 onDrawerSlide 方法,并且实际上在我的 MainActivity 中设置了它,以便在抽屉打开时,如果我在其中一个 fragment 中的 EditText 打开,我调用 hideSoftKeyboard 代码,以便它会关闭软键盘。

我获取抽屉打开事件的代码:(在 MainActivity 的 onCreate() 方法中)

DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
{
            //Hide SoftKeyboard on Navigation Drawer Open
            @Override
            public void onDrawerSlide(View drawerView, float slideOffset) {
                //Hide SoftKeyboard if it is open
                hideSoftKeyboard();

                //And Make any view having focus loose focus
 //...
//ClearFocus for the whole view is done from here (for whichever Fragment is visible right now)

                super.onDrawerSlide(drawerView, slideOffset);
            }        
};

public void hideSoftKeyboard()    //Declared outside onCreate
{
        InputMethodManager inputMethodManager = (InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE);
        inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}

在这里,我的 hideSoftKeyboard() 代码是通用的,并且可以关闭 SoftKeyboard,无论此时从 MainActivity 本身可见什么 Fragment . 同样我想clearFocus 我所有的EditTexts 和TextView(因为复制/粘贴选项在抽屉打开时显示在中间)。

我知道我可以为每个 Fragment 编写代码调用 onDrawerSlide 函数并分别为每个元素清除 Focus,但我想知道通用解决方案是否可行,如果可行,如何实现。

(如果可能的话,这可能会有很多影响,并且在很多情况下可能会有所帮助)

最佳答案

好吧,我终于决定不能再等待一般性答案了,因此决定为每个 fragment 实现onDrawerSlide。事实证明,即使这样也有点棘手,因为您需要访问工具栏并使用当前抽屉设置抽屉,并且进行一些试验会抛出 NPE! (只是我平时的运气)

当我想到这一点时,正在浏览官方 android 开发者网站以获取任何见解。为什么不使用 getCurrentFocus 获取我当前的 View ,然后使用 clearFocus()!瞧,它有效。我过于关注复杂的情况,以至于忘记检查简单的部分。

所以这是我自己的问题的答案:(在 MainActivity 的 onCreate 中)

DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
{
            @Override
            public void onDrawerSlide(View drawerView, float slideOffset) {
                hideSoftKeyboard();

                getCurrentFocus().clearFocus();  //clear focus - any view having focus

                super.onDrawerSlide(drawerView, slideOffset);
}

感谢@keivan Esbati 指出了一个我没有注意到的漏洞,因为我使用了虚拟 View (在布局 xml 中使用,因此一旦加载布局,第一个 EditText 就不会获得焦点)。根据 Android 开发者论坛:

clearFocus() : When a View clears focus the framework is trying to give focus to the first focusable View from the top. Hence, if this View is the first from the top that can take focus, then all callbacks related to clearing focus will be invoked after which the framework will give focus to this view.

为此当然要设置一个虚拟变量,一旦加载布局(我使用的方法)或 this 就会调用焦点。由@keivan 分享。

关于android - 如何清除 View 中所有可选元素的焦点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42473406/

相关文章:

java - 是否可以将 FragmentActivity 放入 fragment 容器中?

android - 有没有办法在单击按钮时删除 firebase 数据库父节点?

wpf - 我该如何让那个该死的 wpf 弹出窗口消失?

android - 在带有标题和列表的 NavigationDrawer 中使用自定义布局

android - 如何更改 NavigationView 中的分隔符颜色?

java - android无法在自定义对话框中的 ListView 中使用获取所有编辑文本值

java - 如何更新 navMenuIcons 上的数字

java - 最小化框架中的机器人焦点

c# - 在WinForms中可以控制焦点变化 "automatically"?如果是,我可以以某种方式将其与用户触发的焦点更改区分开来吗?

android - 如何在 NavigationView 中的项目上添加徽章