硬件键盘按键时汉堡图标自动获焦,如何阻止该行为?
解决硬件按键触发时汉堡图标自动获焦的问题
这个问题我做项目时也碰到过,本质是Android焦点管理的默认行为在作祟——当硬件键盘有输入时,系统会自动扫描界面上可聚焦的View,而Toolbar的汉堡导航按钮默认是可聚焦状态,所以就被优先选中了。给你几个实用的解决办法:
方法一:直接禁用导航按钮的可聚焦性
最直接的方式就是把汉堡按钮的可聚焦属性关掉,让系统不会把焦点分配给它。
如果是在Fragment里操作Toolbar,可以在onViewCreated方法里添加这段代码:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val toolbar = view.findViewById<Toolbar>(R.id.your_toolbar_id) // 禁用导航图标的可聚焦性 toolbar.navigationIcon?.apply { isFocusable = false isFocusableInTouchMode = false } }
如果用的是Java:
@Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); Toolbar toolbar = view.findViewById(R.id.your_toolbar_id); if (toolbar.getNavigationIcon() != null) { toolbar.getNavigationIcon().setFocusable(false); toolbar.getNavigationIcon().setFocusableInTouchMode(false); } }
要是你用了ActionBarDrawerToggle来关联抽屉和Toolbar,也可以直接给toggle设置不可聚焦:
val toggle = ActionBarDrawerToggle( requireActivity(), drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close ) toggle.isFocusable = false toggle.isFocusableInTouchMode = false drawerLayout.addDrawerListener(toggle) toggle.syncState()
方法二:指定优先聚焦的视图
如果你的界面里有输入框、按钮等需要优先获取焦点的控件,可以主动让它请求焦点,这样系统就不会把焦点给到汉堡按钮了:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val targetView = view.findViewById<EditText>(R.id.your_input_view) targetView.requestFocus() }
也可以在布局文件里给目标控件设置android:focusable="true"和android:focusableInTouchMode="true",确保它能被系统优先识别。
方法三:拦截硬件按键事件(谨慎使用)
如果前两种方法都不满足需求,你可以尝试拦截硬件按键事件,阻止系统自动分配焦点。注意不要拦截返回键、菜单键等系统关键按键:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val rootLayout = view.findViewById<RelativeLayout>(R.id.root_layout) rootLayout.setOnKeyListener { _, keyCode, _ -> // 只拦截非系统关键按键 when(keyCode) { KeyEvent.KEYCODE_BACK, KeyEvent.KEYCODE_MENU -> false // 交给系统处理 else -> true // 拦截事件,阻止焦点跳转 } } }
小提示
如果第一种方法没生效,大概率是因为导航按钮的实际视图是ActionBarDrawerToggle的内部控件,这时候直接给toggle设置不可聚焦属性会更可靠。另外,尽量避免在布局文件里直接给Toolbar设置android:focusable="false",因为导航图标是动态添加的,布局属性可能覆盖不到它。
内容的提问来源于stack exchange,提问作者Alexey Nikitin
相关产品推荐
相关产品推荐

