如何获得具有焦点的 ViewPager 以将 dispatchKeyEvent() 传递给其 children 视图?

How do I get a ViewPager with focus to pass a dispatchKeyEvent() to its children views?

我有一个 ViewPager 的对话框 child 视图,我有一个 setOnKeyListener() 和 setOnClickListener() 设置。但是,即使 child 视图在应用程序中处于可见焦点(它是 ViewPager 上的对话框),也不会在按键时调用侦听器。进一步的调查似乎表明,如果 ViewPager 具有焦点,它不会传递 dispatchKeyEvent() 。但是,如果我使用以下代码在 ViewPager 上设置 OnKeyListener:

mViewPager.setOnKeyListener(new View.OnKeyListener() {
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_UP
            && event.getKeyCode() == KeyEvent.KEYCODE_DPAD_CENTER) {

            final int childIndex = mViewPager.getCurrentItem();
            mViewPager.getChildAt(childIndex).performClick();
        }
        return false;
    }
});

child 上的显式点击调用将激活 OnClickListener。但是,我真的不应该那样做。该事件应该向下传递到视图层次结构中。这是普遍接受的处理方式吗?必须像这样显式调用 child 感觉不对。

显然这是有意为之的行为。为了让 children 接收事件,ViewPager 需要代码来显式处理它。部分原因似乎是即使向 PageViewer 提供了大量视图,通常也只有一个子集被主动缓存并且可以调用方法。如果我想让所有 children 都对点击做出反应,我需要做类似的事情:

for(int i=0; i<mViewPager.getChildCount(); i++){
    mViewPager.getChildAt(i).performClick();
}

如果您的 child 视图设置了 OnClickListener,那么它将对点击做出反应,但前提是该视图当前位于活动的 ViewPager 缓存中。如果您的视图具有某种可以根据操作更改的状态(例如单击时出现新的可绘制对象并在单击时消失)那么我发现使所有视图 children 受到影响的唯一方法似乎是您需要有一个控制器来跟踪状态并设置一个 OnPageChangeListener 遍历 "active" children Views 并确保它们都处于正确的状态。