天天看點

機頂盒焦點控制

常見預設擷取焦點的元件:EditText、Scrollbar

常見不會預設擷取焦點的元件:FrameLayout、LinearLayout、ImageView、Button、TextView

将元件設定clickable = true,則相當于将元件設定為focusable = true

焦點的時間分發機制:焦點的事件分發機制

避免焦點丢失(設定焦點不跑出子View中):大體思路,通過目前已經擷取焦點的view ,以及按鍵的方向,去尋找下一個可以擷取焦點的view,代碼展示:

FocusFinder.getInstance().findNextFocus(ViewGroup root, View focused, int direction)

,如果傳回為null,說明在該方向,擷取不到焦點。可以直接 return true 消費該按鍵,則不會再繼續尋找焦點。

open class FocusLinearLayout @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) {
    private lateinit var mFocusView: View

    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
        var mDirection = 0
        if (event.action == KeyEvent.ACTION_DOWN) {
            when (event.keyCode) {
                KeyEvent.KEYCODE_DPAD_LEFT ->
                    mDirection = View.FOCUS_LEFT
                KeyEvent.KEYCODE_DPAD_RIGHT ->
                    mDirection = View.FOCUS_RIGHT
                KeyEvent.KEYCODE_DPAD_UP ->
                    mDirection = View.FOCUS_UP
                KeyEvent.KEYCODE_DPAD_DOWN ->
                    mDirection = View.FOCUS_DOWN
            }
            if (mDirection != 0) {
                val findNextFocus = FocusFinder.getInstance().findNextFocus(this, mFocusView, mDirection) ?: return true
            }
        }
        return super.dispatchKeyEvent(event)
    }

    override fun requestChildFocus(child: View?, focused: View) {
        mFocusView = focused
        super.requestChildFocus(child, focused)
    }
}
           

繼續閱讀