DispatchKeyEvent没有在我的View上触发

时间:2017-06-11 22:10:33

标签: c# android xamarin keyboard xamarin.android

我需要拦截CustomView中的物理键事件,所以我写了这个:

   public class CustomView : View
   {
        public override bool DispatchKeyEvent(KeyEvent e)
        {
            return base.DispatchKeyEvent(e);
        }
    }

当我按任意键时,我不知道为什么DispatchKeyEvent 从未被调用

我怎样才能让它发挥作用?

注意:似乎在活动中覆盖相同的方法,它可以工作,但我需要在 CustomView 中执行此操作。

1 个答案:

答案 0 :(得分:1)

customView FocusedFocusableInTouchMode = true之后,您可以抓住KeyEvent。从DispatchEvent源代码中我们可以看到:

@Override
public boolean dispatchKeyEvent(KeyEvent event) {

    if ((mPrivateFlags & (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS))
            == (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS)) {
        // If this ViewGroup is focused and its size has been set(has border),pass the KeyEvent to the view

        if (super.dispatchKeyEvent(event)) {
            return true;
        }
    } else if (mFocused != null && (mFocused.mPrivateFlags & PFLAG_HAS_BOUNDS)
            == PFLAG_HAS_BOUNDS) {
        //If this ViewGroup has a focused child,and the child has a size
        if (mFocused.dispatchKeyEvent(event)) { 
            return true; 
           // We can see that only the child is focused it can be catch the key event
        }
    }

    if (mInputEventConsistencyVerifier != null) {
        mInputEventConsistencyVerifier.onUnhandledEvent(event, 1);
    }
    return false;
}

因此,customView必须专注于捕捉KeyEvent

我解决了这个问题,请将此代码添加到customView

public GameView(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
{
     //Set whether this view can receive the focus
     this.Focusable = true;

    //When a view is focusable, it may not want to take focus when in touch mode.
    //For example, a button would like focus when the user is navigating via a D-pad
    //so that the user can click on it, but once the user starts touching the screen,
    //the button shouldn't take focus
     this.FocusableInTouchMode = true;
}

//Returns whether this View is able to take focus
public override bool IsFocused => true;