android TV 开发知识点记录

本文记录作者自己在开发Android TV应用的时候遇到的问题并记录之,供后续查漏补缺。


1. Android 原生控件的 Focusable 的默认值的问题?

一般系统的自带控件focusable 的值,有 button及其子类RadioButton、CheckedBox , EditText,还有ListView,Recycleiew 等列表类控件为true, 其余的都为false。

  View[] viewFocusable = new View[]{mButton, mLinearLayout, mImageView, mImageButton, mView, mTextView, mEditText, frameLayout ,relativeLayout};
        for (View v: viewFocusable) {
            Log.d(TAG, v.toString() + "focusable 的值为:" + v.isFocusable());
        }


打印的值为:

android.support.v7.widget.AppCompatButton{4221f9d8 VFED..C. ......I. 0,0-0,0 #7f090043 app:id/btn}focusable 的值为:true
android.widget.LinearLayout{4227c2d8 VFE..... ......I. 0,0-0,0 #7f0900db app:id/llayout}focusable 的值为:true
android.support.v7.widget.AppCompatImageView{421f5280 V.ED.... ......I. 0,0-0,0 #7f0900aa app:id/imageView}focusable 的值为:false
android.support.v7.widget.AppCompatImageButton{41fe4670 VFED..C. ......I. 0,0-0,0 #7f0900a9 app:id/imageButton}focusable 的值为:true
android.view.View{421d7400 V.ED.... ......I. 0,0-0,0 #7f090150 app:id/view}focusable 的值为:false
android.support.v7.widget.AppCompatTextView{4221b9b0 V.ED.... ......ID 0,0-0,0 #7f09014a app:id/tv}focusable 的值为:false
android.support.v7.widget.AppCompatEditText{42222650 VFED..CL ......I. 0,0-0,0 #7f090079 app:id/et}focusable 的值为:true
android.widget.FrameLayout{421e12f0 V.E..... ......I. 0,0-0,0 #7f090084 app:id/frameLayout}focusable 的值为:false
android.widget.RelativeLayout{41fe4f90 V.E..... ......I. 0,0-0,0 #7f09010c app:id/rlLayout}focusable 的值为:false

针对第二个linearLayout 的值为 true, 是因为在xml中 设置focusable = true 导致的。一般的,容器控件的view 其 focusable 都为 false,除非你设置了。

那针对ListView、recycleView这种控件呢, 以及他们的Item 呢?

答案是他们默认是True, 他们和一般容器控件不一样 。以ListView为例,体统源码中有设置:setFocusableInTouchMode(true);

同理recycleView也都一样。而对于item而言,我们需要进行设置

private boolean mItemsCanFocus = false;

    /**
     * Indicates that the views created by the ListAdapter can contain focusable
     * items.
     *
     * @param itemsCanFocus true if items can get focus, false otherwise
     */
    public void setItemsCanFocus(boolean itemsCanFocus) {
        mItemsCanFocus = itemsCanFocus;
        if (!itemsCanFocus) {
            setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
        }
    }

    /**
     * @return Whether the views created by the ListAdapter can contain focusable
     * items.
     */
    public boolean getItemsCanFocus() {
        return mItemsCanFocus;
    }

上面是ListView中关于item能否聚焦的核心代码,一看就明了。而RecycleView 对于item而言,则需要在

@Override
    public void onBindViewHolder(@NonNull final Holder holder, int i) {

        //设置item 可以点击
        holder.itemView.setFocusable(true);
        holder.itemView.setFocusableInTouchMode(true);
    }

2. 当用遥控器控制焦点移动时,其会遵循一个什么样的规律呢?

一般来说:系统会自动的把焦点移到距离最近的可触控的控件(focusable为true),所以当我们在一个viewGroup (没有进行特殊设置)包裹了一个可以的点击的Button,这时候他会自动的把焦点聚焦在button上,如果你对ViewGroup 进行设置可聚焦,那么焦点会获取焦点,button就无法聚焦,除非你对viewGroup 进行 onFocusableChangeListener监听,并让button 强制获取焦点

v.setOnFocusChangeListener(new View.OnFocusChangeListener() {
                @Override
                public void onFocusChange(View v, boolean hasFocus) {
                    if(hasFocus){
                        Log.d(TAG, "onFocusChange: hasFocus" + v.toString());
                        // do something
                    }else {
                        // do something
                        Log.d(TAG, "onFocusChange: lostFocus" + v.toString());
                    }
                }
            });

猜你喜欢

转载自blog.csdn.net/sjh_389510506/article/details/86665722