android - 在 Android 中,是否可以在关键事件到达具有焦点的 subview 之前全局拦截它们?

标签 android events event-handling keyboard key

在大多数情况下,我希望关键事件由当前具有焦点的(子) View 处理,这是默认行为,也是我目前已经实现的。

但是,在某些非常特殊的情况下,我想在我当前的 Activity 中或在我的 Root View 中临时拦截和处理所有关键事件(特别包括那些通常由 subview 处理的事件)没关系,只要它们是全局处理的——我不关心音量 +/- 之类的硬件按钮,因为这些按钮无论如何都不会在我的任何 subview 中处理)。

对于 touch 事件,我们有 onInterceptTouchEvent(),它允许 ViewGroup 在将触摸事件分派(dispatch)给 subview 时观察触摸事件,并阻止 subview 接收这些事件(在需要时)它们所针对的 View 。

不幸的是,我找不到任何类似于 onInterceptTouchEvent() 的关键事件。我是否遗漏了一些明显的东西,或者这是操作系统中的实际不对称?

当然,我可以只连接每个 subview 的当前关键事件处理程序代码,以直接调用主 Activity 上的方法来处理事件(如果需要),并让该 Activity 级别的方法返回一个 bool 值指示它是否处理了该事件。然后,当且仅当它调用的 Activity 方法没有处理它时, subview 才能处理该事件。

但我希望有一种更简洁的方法来简单地拦截在层次结构“向下”到达 subview 的过程中的流量,就像 onInterceptTouchEvent() 对触摸事件所做的那样。

最佳答案

您可以将 OnGlobalFocusChangeListener 添加到您的 Root View 。让我们针对每个 Activity 执行此操作:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    findViewById(android.R.id.content).getViewTreeObserver().addOnGlobalFocusChangeListener(new ViewTreeObserver.OnGlobalFocusChangeListener() {
        @Override
        public void onGlobalFocusChanged(View oldFocus, View newFocus) {
            if (newFocus instanceof EditText) {
                ((EditText) newFocus).addTextChangedListener(new TextWatcher() {
                    @Override
                    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                        //process whatever you want
                    }

                    @Override
                    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                    }

                    @Override
                    public void afterTextChanged(Editable editable) {
                    }
                });
            }
        }
    });
}

当然,如果您对 EditText 以外的 View 感兴趣,您必须弄清楚如何观察它们的变化。

此外,如果您想将其全局添加到您的所有 Activity 中,请使用 Application#registerActivityLifecycleCallbacks() 在您的所有 Activity 中使用该代码。

关于android - 在 Android 中,是否可以在关键事件到达具有焦点的 subview 之前全局拦截它们?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14890720/

相关文章:

Jquery - 将点击事件处理程序添加到由自动完成生成的 <li>

android - Eclipse 缓冲区溢出谷歌眼镜

android - 为什么我的 flutter 应用程序启动器图标是一个圆圈?我可以用方形图标来代替这个吗?

javascript - Firefox 没有在周围的 div 上注册点击事件

javascript - 如何用Javascript实现一个完整的事件系统?

javascript:可以添加在默认行为之后运行的事件处理程序吗?

javascript - 如何在 React.js 中使用 onClick 和 div

android – 如何检查webview是否可用?

java - 尝试从java访问MySQL,但它不工作

android - 从 CursorAdapter 事件调用 ListFragment 中的自定义监听器