Android TV 焦点控制实例

Android TV 焦点控制实例,第1张

概述首先上实例:项目工程文件:    界面布局:activity_tab.xml:<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apkes/android"xmlns:app="http://schemas.android.com/apkes

首先上实例:

项目工程文件:

 

 

 

 

界面布局:

activity_tab.xml:

<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"    xmlns:app="http://schemas.androID.com/apk/res-auto"    xmlns:tools="http://schemas.androID.com/tools"    androID:layout_wIDth="match_parent"    androID:layout_height="match_parent"    androID:background="@color/fastlane_background"    androID:orIEntation="vertical"    tools:context=".activity.tabactivity">    <androIDx.recyclervIEw.Widget.RecyclerVIEw        androID:ID="@+ID/rv_tan"        androID:layout_wIDth="match_parent"        androID:layout_height="0dp"        androID:layout_weight="1"        androID:descendantFocusability="afterDescendants"        app:layout_constraintleft_toleftOf="parent"        app:layout_constraintleft_toRightOf="parent"        app:layout_constrainttop_totopOf="parent" />    <linearLayout        androID:layout_wIDth="match_parent"        androID:layout_height="0dp"        androID:layout_weight="4"        androID:orIEntation="horizontal">        <ImageVIEw            androID:ID="@+ID/main_img"            androID:layout_wIDth="0dp"            androID:layout_height="match_parent"            androID:layout_weight="2"            androID:background="@drawable/bg_recyclervIEw_item"            androID:focusable="true"            androID:focusableIntouchMode="true"            androID:padding="15dp"            androID:src="@drawable/pro2"            />       <!-- <androIDx.recyclervIEw.Widget.RecyclerVIEw            androID:ID="@+ID/main_tab_rv"            androID:layout_wIDth="0dp"            androID:layout_height="match_parent"            androID:layout_weight="2"/>-->        <com.example.focusdome.vIEw.FocusRecyclerVIEw            androID:ID="@+ID/main_tab_rv"            androID:layout_wIDth="0dp"            androID:layout_height="match_parent"            androID:layout_weight="1"            />    </linearLayout>    <linearLayout        androID:layout_wIDth="match_parent"        androID:layout_height="0dp"        androID:layout_weight="1">    <androIDx.recyclervIEw.Widget.RecyclerVIEw        androID:ID="@+ID/button_tab_rv"        androID:layout_wIDth="wrap_content"        androID:layout_height="wrap_content"        />    </linearLayout></linearLayout>

layout_found_h_recycler_item.xml:

<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:layout_wIDth="wrap_content"    androID:layout_height="wrap_content"    androID:orIEntation="vertical"    androID:focusable="true"    androID:background="@drawable/bg_recyclervIEw_item"    androID:padding="20dp"    >    <com.example.focusdome.vIEw.circleimageVIEw        androID:ID="@+ID/f_h_c_img"        androID:layout_wIDth="109dp"        androID:layout_height="0dp"        androID:layout_gravity="center"        androID:layout_weight="3"        androID:src="@drawable/pro5"        />    <TextVIEw        androID:ID="@+ID/f_h_c_txt"        androID:layout_wIDth="120dp"        androID:layout_height="0dp"        androID:layout_weight="1"        androID:gravity="center"        androID:text="1111"        androID:textSize="10dp"        /></linearLayout>

layout_main_recycler_txtrecycler.xml

<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:layout_wIDth="match_parent"    androID:layout_height="wrap_content"    androID:focusable="true"    androID:background="@drawable/bg_recyclervIEw_item"    >    <TextVIEw        androID:ID="@+ID/main_rv_rv_txt"        androID:layout_wIDth="match_parent"        androID:layout_height="60dp"        androID:gravity="center"        /></linearLayout>

layout_recycler_text_item.xml

<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:layout_wIDth="wrap_content"    androID:layout_height="wrap_content"    androID:layout_gravity="center"    androID:orIEntation="horizontal"    androID:gravity="center"    androID:background="@drawable/bg_recyclervIEw_item"    androID:focusable="true">    <TextVIEw        androID:ID="@+ID/tv"        androID:layout_wIDth="120dp"        androID:layout_height="60dp"        androID:textcolor="#ffffff"        androID:textSize="16sp"        androID:text=""        androID:padding="10dp"        androID:gravity="center"        /></linearLayout>

资源文件:

bg_recyclervIEw_item.xml

 

<?xml version="1.0" enCoding="utf-8"?><selector xmlns:androID="http://schemas.androID.com/apk/res/androID">    <item androID:drawable="@drawable/bg_recyclervIEw_focus" androID:state_selected="true" />    <item androID:drawable="@drawable/bg_recyclervIEw_focus" androID:state_focused="true" />    <item androID:drawable="@drawable/bg_recyclervIEw_focus" androID:state_pressed="true" />    <item androID:drawable="@color/transparent"/></selector>

bg_recyclervIEw_focus.xml:

<?xml version="1.0" enCoding="utf-8"?><@R_64_3419@ xmlns:androID="http://schemas.androID.com/apk/res/androID">    <item>        <shape androID:shape="rectangle">            <solID androID:color="#80B469FF" />            <corners androID:radius="10dp" />        </shape>    </item>    <item androID:bottom="2dp"        androID:left="2dp"        androID:right="2dp"        androID:top="2dp">        <shape androID:shape="rectangle">            <solID androID:color="#60B469FF" />            <corners androID:radius="8dp" />        </shape>    </item>    <item        androID:bottom="5dp"        androID:left="5dp"        androID:right="5dp"        androID:top="5dp">        <shape            androID:layout_wIDth="wrap_content"            androID:shape="rectangle">            <stroke                androID:wIDth="1dp"                androID:color="#6672f8" />        </shape>    </item>    <item        androID:bottom="6dp"        androID:left="6dp"        androID:right="6dp"        androID:top="6dp">        <shape androID:shape="rectangle">            <stroke                androID:wIDth="1dp"                androID:color="#6672f8" />        </shape>    </item>    <item        androID:bottom="7dp"        androID:left="7dp"        androID:right="7dp"        androID:top="7dp">        <color androID:color="@color/color_141843"/>    </item></@R_64_3419@>

activity代码:

package com.example.focusdome.activity;import androIDx.appcompat.app.AppCompatActivity;import androIDx.core.vIEw.VIEwCompat;import androIDx.recyclervIEw.Widget.linearlayoutmanager;import androIDx.recyclervIEw.Widget.RecyclerVIEw;import androID.app.Activity;import androID.os.Bundle;import androID.util.Log;import androID.vIEw.KeyEvent;import androID.vIEw.LayoutInflater;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.ImageVIEw;import androID.Widget.TextVIEw;import androID.Widget.Toast;import com.example.focusdome.R;import com.example.focusdome.adapter.BtnRecyclerVIEwAdapter;import com.example.focusdome.adapter.MainRecyclerVIEwAdapter;import com.example.focusdome.adapter.MyRecyclerVIEwAdapter;import com.example.focusdome.model.RecyclerMainModel;import com.example.focusdome.vIEw.Focuslinearlayoutmanager;import com.example.focusdome.vIEw.Spacedecoration;import java.util.ArrayList;public class tabactivity extends Activity implements MyRecyclerVIEwAdapter.OnItemClickListener,MyRecyclerVIEwAdapter.OnItemFocuschangelistener{    private MyRecyclerVIEwAdapter adapter;    private RecyclerVIEw recyclerVIEw;    private String[] Titles = {"首页", "游戏","教育","生活","娱乐","新闻","直播","我的"};    private ImageVIEw imageVIEw;    //主体部分    private MainRecyclerVIEwAdapter mAdapter;    private RecyclerVIEw mainRecyclerVIEw;    private ArrayList<RecyclerMainModel> List = new ArrayList<>();   //底部部分    private BtnRecyclerVIEwAdapter btnRecyclerVIEwAdapter;    private RecyclerVIEw btnRecyclerVIEw;    @OverrIDe    protected voID onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentVIEw(R.layout.activity_tab);        initVIEw();        initAdapter();        //初始化主体部分recycle        mainRecyclerVIEw = findVIEwByID(R.ID.main_tab_rv);        List.add(new RecyclerMainModel("第一张",R.drawable.pre));        List.add(new RecyclerMainModel("第二张",R.drawable.pro));        List.add(new RecyclerMainModel("第三张",R.drawable.pro2));        List.add(new RecyclerMainModel("第四张",R.drawable.pro3));        List.add(new RecyclerMainModel("第五张",R.drawable.pro4));        List.add(new RecyclerMainModel("第六张",R.drawable.hp_one));        List.add(new RecyclerMainModel("第七张",R.drawable.hp_four));        List.add(new RecyclerMainModel("第八张",R.drawable.hp_five));        mAdapter = new MainRecyclerVIEwAdapter(this, List, new MainRecyclerVIEwAdapter.OnItemClickListener() {            @OverrIDe            public voID onItemClick(VIEw vIEw, int position) {                Log.v("点击:", "" + position + vIEw.getID());                imageVIEw.setimageResource(List.get(position).getM_imgID());                //imageVIEw.setScaleType(ImageVIEw.ScaleType.CENTER);            }        }/*, new MainRecyclerVIEwAdapter.OnItemFocuschangelistener() {            @OverrIDe            public voID onItemFocusChange(VIEw vIEw, int position, boolean hasFocus) {               // Toast.makeText(tabactivity.this,"focus"+position,Toast.LENGTH_LONG).show();                imageVIEw.setimageResource(List.get(position).getM_imgID());            }        }*/) {            //获得焦点时处理            @OverrIDe            protected voID onItemFocus(VIEw itemVIEw,int positon) {               imageVIEw.setimageResource(List.get(positon).getM_imgID());               System.out.println("获取焦点成功!"+positon);                Log.i("vIEw:",itemVIEw.getID()+"23333");                itemVIEw.setSelected(true);                VIEw vIEw = itemVIEw.findVIEwByID(R.ID.main_rv_rv_txt);                vIEw.setSelected(true);            }            //失去焦点时            @OverrIDe            protected voID onItemGetnormal(VIEw itemVIEw) {                System.out.println("失去焦点成功!");                Log.i("vIEw:",itemVIEw.getID()+"32222");               itemVIEw.setSelected(false);                VIEw vIEw = itemVIEw.findVIEwByID(R.ID.main_rv_rv_txt);                vIEw.setSelected(true);            }        };        Focuslinearlayoutmanager linearlayoutmanager = new Focuslinearlayoutmanager(this,linearlayoutmanager.VERTICAL,false);        mainRecyclerVIEw.setLayoutManager(linearlayoutmanager);        mainRecyclerVIEw.addItemdecoration(new Spacedecoration(30));        mainRecyclerVIEw.setAdapter(mAdapter);        //初始化底部部分        btnRecyclerVIEw = (RecyclerVIEw)findVIEwByID(R.ID.button_tab_rv);        btnRecyclerVIEwAdapter = new BtnRecyclerVIEwAdapter(this, List) {            @OverrIDe            protected voID onItemFocus(VIEw itemVIEw, int position) {                itemVIEw.setSelected(true);                //VIEw vIEw = itemVIEw.            }            @OverrIDe            protected voID onItemGetnormal(VIEw itemVIEw) {                   itemVIEw.setSelected(false);            }        };        Focuslinearlayoutmanager linearlayoutmanager1 = new Focuslinearlayoutmanager(this,linearlayoutmanager.HORIZONTAL,false);        btnRecyclerVIEw.setLayoutManager(linearlayoutmanager1);        btnRecyclerVIEw.setAdapter(btnRecyclerVIEwAdapter);    }    private voID initVIEw() {        recyclerVIEw = findVIEwByID(R.ID.rv_tan);        imageVIEw= findVIEwByID(R.ID.main_img);        imageVIEw.setonFocuschangelistener(new VIEw.OnFocuschangelistener() {            @OverrIDe            public voID onFocusChange(VIEw vIEw, boolean b) {                Log.v("img_focus",""+vIEw.getID());            }        });    }    private voID initAdapter() {        adapter = new MyRecyclerVIEwAdapter(this, Titles);        linearlayoutmanager linearlayoutmanager = new linearlayoutmanager(this,linearlayoutmanager.HORIZONTAL,false);        recyclerVIEw.setLayoutManager(linearlayoutmanager);        recyclerVIEw.setAdapter(adapter);        recyclerVIEw.requestFocus();        adapter.setmOnItemClickListener(this);        adapter.setmOnItemClickListener(this);    }    @OverrIDe    public voID onItemClick(VIEw vIEw, int position) {        Log.i("Activity:onItemClick","mOnItemFocuschangelistener.onItemFocusChange(v, position, hasFocus);");    }    @OverrIDe    public voID onItemFocusChange(VIEw vIEw, int position, boolean hasFocus) {    }    @OverrIDe    public boolean onKeyDown(int keyCode, KeyEvent event) {                return super.onKeyDown(keyCode, event);    }    @OverrIDe    public boolean dispatchKeyEvent(KeyEvent event) {        //VIEw v =  getCurrentFocus();        return super.dispatchKeyEvent(event);    }}

adapter代码:

其余的adapter基本和这个差不多

package com.example.focusdome.adapter;import androID.content.Context;import androID.os.Build;import androID.util.Log;import androID.vIEw.LayoutInflater;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.ImageVIEw;import androID.Widget.TextVIEw;import androIDx.annotation.NonNull;import androIDx.annotation.Nullable;import androIDx.core.vIEw.VIEwCompat;import androIDx.recyclervIEw.Widget.linearlayoutmanager;import androIDx.recyclervIEw.Widget.RecyclerVIEw;import com.example.focusdome.R;import com.example.focusdome.activity.tabactivity;import com.example.focusdome.model.RecyclerMainModel;import java.util.ArrayList;public abstract class BtnRecyclerVIEwAdapter extends RecyclerVIEw.Adapter<RecyclerVIEw.VIEwHolder> {    private Context context;    private ArrayList<RecyclerMainModel> data;    private MyRecyclerVIEwAdapter.OnItemFocuschangelistener mOnItemFocuschangelistener;    private MyRecyclerVIEwAdapter.OnItemClickListener mOnItemClickListener;    private final LayoutInflater layoutInflater;    private int defaultFocus = 0;    private boolean needFocus = true;    public BtnRecyclerVIEwAdapter(Context context, ArrayList<RecyclerMainModel> List) {        this.context = context;        this.data = List;        layoutInflater = LayoutInflater.from(context);    }    public interface OnItemClickListener{        voID onItemClick(VIEw vIEw, int position);    }    public interface OnItemFocuschangelistener{        voID onItemFocusChange(VIEw vIEw, int position, boolean hasFocus);    }    public final voID setmOnItemClickListener(@Nullable MyRecyclerVIEwAdapter.OnItemClickListener Listener){        mOnItemClickListener = Listener;    }    private voID setmOnItemFocuschangelistener(@Nullable MyRecyclerVIEwAdapter.OnItemFocuschangelistener focuschangelistener){        this.mOnItemFocuschangelistener = focuschangelistener;    }    @NonNull    @OverrIDe    public RecyclerVIEw.VIEwHolder onCreateVIEwHolder(@NonNull VIEwGroup parent, int vIEwType) {        VIEw v = layoutInflater.inflate(R.layout.layout_found_h_recycler_item,parent,false);        return  new RecyclerVIEwHolder(v);    }    @OverrIDe    public voID onBindVIEwHolder(@NonNull RecyclerVIEw.VIEwHolder holder,final int position) {        RecyclerVIEwHolder vIEwHolder = (RecyclerVIEwHolder)holder;        vIEwHolder.imageVIEw.setimageResource(data.get(position).getM_imgID());        vIEwHolder.textVIEw.setText(data.get(position).getM_txt());        if (mOnItemClickListener != null) {            holder.itemVIEw.setonClickListener(new VIEw.OnClickListener() {                @OverrIDe                public voID onClick(VIEw v) {                    mOnItemClickListener.onItemClick(v, position);                    Log.e("click事件:","你点击了"+v.getID());                }            });        }            holder.itemVIEw.setonFocuschangelistener(new VIEw.OnFocuschangelistener() {                @OverrIDe                public voID onFocusChange(VIEw v, boolean hasFocus) {                  if (hasFocus){                      focusstatus(v,position);                  }else {                      normalStatus(v);                  }                    Log.i("adapter:","onFocusChange");                }            });        if (needFocus) {            Log.i("进行移动:",":");            if (defaultFocus < 0) {                defaultFocus = 0;            }            if (defaultFocus >= getItemCount()) {                defaultFocus = getItemCount() - 1;            }            if (defaultFocus == position) {                if (!holder.itemVIEw.isFocusable()) {                    defaultFocus++;                } else {                    holder.itemVIEw.requestFocus();                }            }        } else {            //setNeedFocus(position == (getItemCount() - 1));        }    }    @OverrIDe    public int getItemCount() {        return data.size();    }    private class RecyclerVIEwHolder extends RecyclerVIEw.VIEwHolder {        public TextVIEw textVIEw;        public ImageVIEw imageVIEw;        public RecyclerVIEwHolder(@NonNull VIEw itemVIEw) {            super(itemVIEw);            textVIEw = (TextVIEw) itemVIEw.findVIEwByID(R.ID.f_h_c_txt);            imageVIEw = (ImageVIEw)itemVIEw.findVIEwByID(R.ID.f_h_c_img);        }    }    /**     * item获得焦点时调用     *     * @param itemVIEw vIEw     */    private voID focusstatus(VIEw itemVIEw,int position) {        if (itemVIEw == null) {            return;        }        float scalX,scalY;        scalX = 1.1f;        scalY = 1.1f;        if (Build.VERSION.SDK_INT >= 21) {            //抬高Z轴            VIEwCompat.animate(itemVIEw).scaleX(scalX).scaleY(scalY).translationZ(1.3f).start();        } else {            VIEwCompat.animate(itemVIEw).scaleX(scalX).scaleY(scalY).start();            VIEwGroup parent = (VIEwGroup) itemVIEw.getParent();            parent.requestLayout();            parent.invalIDate();        }        onItemFocus(itemVIEw,position);    }    /**     * 当item获得焦点时处理     *     * @param itemVIEw itemVIEw     */    protected abstract voID onItemFocus(VIEw itemVIEw,int position);    /**     * item失去焦点时     *     * @param itemVIEw item对应的VIEw     */    private voID normalStatus(VIEw itemVIEw) {        if (itemVIEw == null) {            return;        }        if (Build.VERSION.SDK_INT >= 21) {            VIEwCompat.animate(itemVIEw).scaleX(1.0f).scaleY(1.0f).translationZ(0).start();        } else {            VIEwCompat.animate(itemVIEw).scaleX(1.0f).scaleY(1.0f).start();            VIEwGroup parent = (VIEwGroup) itemVIEw.getParent();            parent.requestLayout();            parent.invalIDate();        }        onItemGetnormal(itemVIEw);    }    /**     * 当条目失去焦点时调用     *     * @param itemVIEw 条目对应的VIEw     */    protected abstract voID onItemGetnormal(VIEw itemVIEw);}

model代码:

package com.example.focusdome.model;public class RecyclerMainModel {    private String m_txt;    private int m_imgID;    public RecyclerMainModel(String m_txt, int m_imgID) {        this.m_txt = m_txt;        this.m_imgID = m_imgID;    }    public String getM_txt() {        return m_txt;    }    public voID setM_txt(String m_txt) {        this.m_txt = m_txt;    }    public int getM_imgID() {        return m_imgID;    }    public voID setM_imgID(int m_imgID) {        this.m_imgID = m_imgID;    }}

vIEw代码:

circleimageVIEw.java:

自定义圆形ImageVIEw

package com.example.focusdome.vIEw;import androID.annotation.Suppresslint;import androID.content.Context;import androID.graphics.Bitmap;import androID.graphics.BitmapShader;import androID.graphics.Canvas;import androID.graphics.color;import androID.graphics.Matrix;import androID.graphics.Paint;import androID.graphics.PorterDuff;import androID.graphics.PorterDuffXfermode;import androID.graphics.Rect;import androID.graphics.Shader;import androID.graphics.drawable.BitmapDrawable;import androID.graphics.drawable.Drawable;import androID.os.Build;import androID.util.AttributeSet;import androID.vIEw.VIEw;import androID.Widget.ImageVIEw;import androIDx.annotation.Nullable;import androIDx.annotation.RequiresAPI;@Suppresslint("AppCompatCustomVIEw")public class circleimageVIEw extends ImageVIEw { //画笔    private Paint mPaint;    //圆形图片的半径    private int mRadius;    //图片的宿放比例    private float mScale;    public circleimageVIEw(Context context) {        super(context);    }    public circleimageVIEw(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);    }    public circleimageVIEw(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    @OverrIDe    protected voID onMeasure(int wIDthMeasureSpec, int heightmeasureSpec) {        super.onMeasure(wIDthMeasureSpec, heightmeasureSpec);        //由于是圆形,宽高应保持一致        int size = Math.min(getMeasureDWIDth(), getMeasuredHeight());        mRadius = size / 2;        setMeasuredDimension(size, size);    }    @Suppresslint("DrawAllocation")    @OverrIDe    protected voID onDraw(Canvas canvas) {        mPaint = new Paint();        mPaint.setcolor(color.WHITE);        Drawable drawable = getDrawable();        if (null != drawable) {            Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();            //初始化BitmapShader,传入bitmap对象            BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);            //计算缩放比例            mScale = (mRadius * 2.0f) / Math.min(bitmap.getHeight(), bitmap.getWIDth());            Matrix matrix = new Matrix();            matrix.setScale(mScale, mScale);            bitmapShader.setLocalMatrix(matrix);            mPaint.setShader(bitmapShader);            //画圆形,指定好坐标,半径,画笔            canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);        } else {            super.onDraw(canvas);        }    }}

自定义RecyclerVIEw,重写dispatchKeyEvent()方法,进行焦点控制

FocusRecyclerVIEw:

package com.example.focusdome.vIEw;import androID.content.Context;import androID.util.AttributeSet;import androID.util.Log;import androID.vIEw.FocusFinder;import androID.vIEw.KeyEvent;import androID.vIEw.VIEw;import androIDx.annotation.NonNull;import androIDx.annotation.Nullable;import androIDx.recyclervIEw.Widget.RecyclerVIEw;public class FocusRecyclerVIEw extends RecyclerVIEw {    public FocusRecyclerVIEw(@NonNull Context context) {        super(context);    }    public FocusRecyclerVIEw(@NonNull Context context, @Nullable AttributeSet attrs) {        super(context, attrs);    }    public FocusRecyclerVIEw(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);    }    @OverrIDe    public boolean dispatchKeyEvent(KeyEvent event) {        if (event.getAction() == KeyEvent.ACTION_DOWN) {            int keyCode = event.getKeyCode();            //水平垂直的时候:按下左键或者右键            if (keyCode == KeyEvent.KEYCODE_DPAD_left || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT /*|| keyCode == KeyEvent.KEYCODE_DPAD_DOWN || keyCode == KeyEvent.KEYCODE_DPAD_UP*/) {                //获取当前焦点的视图                VIEw focusedVIEw = getFocusedChild();                VIEw nextFocusVIEw;                try {                   /* switch (keyCode){                        case KeyEvent.KEYCODE_DPAD_left:                            Log.v("left","往左");                            //通过findNextFocus获取下一个需要的焦点的vIE                            nextFocusVIEw = FocusFinder.getInstance().findNextFocus(this,focusedVIEw,VIEw.FOCUS_left);                            break;                        case KeyEvent.KEYCODE_DPAD_RIGHT:                            Log.v("right","往右");                            nextFocusVIEw = FocusFinder.getInstance().findNextFocus(this,focusedVIEw,VIEw.FOCUS_RIGHT);                            break;                        case KeyEvent.KEYCODE_DPAD_UP:                            Log.v("up","往上");                            nextFocusVIEw = FocusFinder.getInstance().findNextFocus(this,focusedVIEw,VIEw.FOCUS_UP);                            break;                        case KeyEvent.KEYCODE_DPAD_DOWN:                            nextFocusVIEw = FocusFinder.getInstance().findNextFocus(this,focusedVIEw,VIEw.FOCUS_DOWN);                            Log.v("down","往下");                            break;                        default:                            nextFocusVIEw = null;                            break;                    }*/                    if (keyCode == KeyEvent.KEYCODE_DPAD_left) {                        Log.v("left", "焦点往左跑");                        //通过findNextFocus获取下一个需要得到的焦点的vIEw                        nextFocusVIEw = FocusFinder.getInstance().findNextFocus(this, focusedVIEw, VIEw.FOCUS_left);                        if(nextFocusVIEw == null){                            Log.v("同级","VIEw查找");                          //  nextFocusVIEw = FocusFinder.getInstance().findNextFocus(this,focusedVIEw.getRootVIEw().,VIEw.FOCUS_left);                             nextFocusVIEw = focusedVIEw.getParent().focusSearch(focusedVIEw,VIEw.FOCUS_left);                        }                    } else {                        Log.v("right", "右边跑");                        //通过findNextFocus获取下一个需要得到的焦点的VIEw                        nextFocusVIEw = FocusFinder.getInstance().findNextFocus(this, focusedVIEw, VIEw.FOCUS_RIGHT);                    }                } catch (Exception e) {                    nextFocusVIEw = null;                }                //如果获取失败,消耗掉事件,不让系统处理,并让原先的vIEw获取焦点                if (nextFocusVIEw == null) {                    focusedVIEw.requestFocus();                    return true;                }            }        }        return super.dispatchKeyEvent(event);    }    @OverrIDe    public VIEw focusSearch(int direction) {        return super.focusSearch(direction);    }}

Spacedecoration.java

package com.example.focusdome.vIEw;import androID.graphics.Canvas;import androID.graphics.color;import androID.graphics.Rect;import androID.graphics.drawable.colorDrawable;import androID.vIEw.VIEw;import androIDx.recyclervIEw.Widget.GrIDLayoutManager;import androIDx.recyclervIEw.Widget.linearlayoutmanager;import androIDx.recyclervIEw.Widget.OrIEntationHelper;import androIDx.recyclervIEw.Widget.RecyclerVIEw;import androIDx.recyclervIEw.Widget.StaggeredGrIDLayoutManager;import com.chad.library.adapter.base.BaseQuickAdapter;import static androID.Widget.linearLayout.VERTICAL;public class Spacedecoration extends RecyclerVIEw.Itemdecoration {    private int space;    private int headerCount = -1;    private int footerCount = Integer.MAX_VALUE;    private boolean mpaddingEdgeSIDe = true;    private boolean mpaddingStart = true;    private boolean mpaddingheaderfooter = false;    private colorDrawable mcolorDrawable;    private boolean mDrawLastItem = true;    private boolean mDrawheaderfooter = false;    public Spacedecoration(int space) {        this.mcolorDrawable = new colorDrawable(color.parsecolor("#e7e7e7"));        this.space = space;    }    public Spacedecoration(int space, int color) {        this.mcolorDrawable = new colorDrawable(color);        this.space = space;    }    public voID setpaddingEdgeSIDe(boolean mpaddingEdgeSIDe) {        this.mpaddingEdgeSIDe = mpaddingEdgeSIDe;    }    public voID setpaddingStart(boolean mpaddingStart) {        this.mpaddingStart = mpaddingStart;    }    public voID setpaddingheaderfooter(boolean mpaddingheaderfooter) {        this.mpaddingheaderfooter = mpaddingheaderfooter;    }    @OverrIDe    public voID getItemOffsets(Rect outRect, VIEw vIEw, RecyclerVIEw parent, RecyclerVIEw.State state) {        int position = parent.getChildAdapterposition(vIEw);        int spanCount = 0;        int orIEntation = 0;        int spanIndex = 0;        int headerCount = 0, footerCount = 0;        if (parent.getAdapter() instanceof BaseQuickAdapter) {            headerCount = ((BaseQuickAdapter) parent.getAdapter()).getheaderLayoutCount();            footerCount = ((BaseQuickAdapter) parent.getAdapter()).getFooterLayoutCount();        }        RecyclerVIEw.LayoutManager layoutManager = parent.getLayoutManager();        if (layoutManager instanceof StaggeredGrIDLayoutManager) {            orIEntation = ((StaggeredGrIDLayoutManager) layoutManager).getorIEntation();            spanCount = ((StaggeredGrIDLayoutManager) layoutManager).getSpanCount();            spanIndex = ((StaggeredGrIDLayoutManager.LayoutParams) vIEw.getLayoutParams()).getSpanIndex();        } else if (layoutManager instanceof GrIDLayoutManager) {            orIEntation = ((GrIDLayoutManager) layoutManager).getorIEntation();            spanCount = ((GrIDLayoutManager) layoutManager).getSpanCount();            spanIndex = ((GrIDLayoutManager.LayoutParams) vIEw.getLayoutParams()).getSpanIndex();        } else if (layoutManager instanceof linearlayoutmanager) {            orIEntation = ((linearlayoutmanager) layoutManager).getorIEntation();            spanCount = 1;            spanIndex = 0;        }        /**         * 普通Item的尺寸         */        if ((position >= headerCount && position < parent.getAdapter().getItemCount() - footerCount)) {            if (orIEntation == VERTICAL) {                float expecteDWIDth = (float) (parent.getWIDth() - space * (spanCount + (mpaddingEdgeSIDe ? 1 : -1))) / spanCount;                float originWIDth = (float) parent.getWIDth() / spanCount;                float expectedX = (mpaddingEdgeSIDe ? space : 0) + (expecteDWIDth + space) * spanIndex;                float originX = originWIDth * spanIndex;                outRect.left = (int) (expectedX - originX);                outRect.right = (int) (originWIDth - outRect.left - expecteDWIDth);                if (position - headerCount < spanCount && mpaddingStart) {                    outRect.top = space;                }                outRect.bottom = space;                return;            } else {                float expectedHeight = (float) (parent.getHeight() - space * (spanCount + (mpaddingEdgeSIDe ? 1 : -1))) / spanCount;                float originHeight = (float) parent.getHeight() / spanCount;                float expectedY = (mpaddingEdgeSIDe ? space : 0) + (expectedHeight + space) * spanIndex;                float originY = originHeight * spanIndex;                outRect.bottom = (int) (expectedY - originY);                outRect.top = (int) (originHeight - outRect.bottom - expectedHeight);                if (position - headerCount < spanCount && mpaddingStart) {                    outRect.left = space;                }                outRect.right = space;                return;            }        } else if (mpaddingheaderfooter) {            if (orIEntation == VERTICAL) {                outRect.right = outRect.left = mpaddingEdgeSIDe ? space : 0;                outRect.top = mpaddingStart ? space : 0;            } else {                outRect.top = outRect.bottom = mpaddingEdgeSIDe ? space : 0;                outRect.left = mpaddingStart ? space : 0;            }        }    }    @OverrIDe    public voID onDraw(Canvas c, RecyclerVIEw parent, RecyclerVIEw.State state) {        if (parent.getAdapter() == null) {            return;        }        int orIEntation = 0;        int headerCount = 0, footerCount = 0, dataCount;        if (parent.getAdapter() instanceof BaseQuickAdapter) {            headerCount = ((BaseQuickAdapter) parent.getAdapter()).getheaderLayoutCount();            footerCount = ((BaseQuickAdapter) parent.getAdapter()).getFooterLayoutCount();            dataCount = parent.getAdapter().getItemCount();        } else {            dataCount = parent.getAdapter().getItemCount();        }        int dataStartposition = headerCount;        int dataEndposition = headerCount + dataCount;        RecyclerVIEw.LayoutManager layoutManager = parent.getLayoutManager();        if (layoutManager instanceof StaggeredGrIDLayoutManager) {            orIEntation = ((StaggeredGrIDLayoutManager) layoutManager).getorIEntation();        } else if (layoutManager instanceof GrIDLayoutManager) {            orIEntation = ((GrIDLayoutManager) layoutManager).getorIEntation();        } else if (layoutManager instanceof linearlayoutmanager) {            orIEntation = ((linearlayoutmanager) layoutManager).getorIEntation();        }        int start, end;        if (orIEntation == OrIEntationHelper.VERTICAL) {            start = parent.getpaddingleft();            end = parent.getWIDth() - parent.getpaddingRight();        } else {            start = parent.getpaddingtop();            end = parent.getHeight() - parent.getpaddingBottom();        }        int childCount = parent.getChildCount();        for (int i = 0; i < childCount; i++) {            VIEw child = parent.getChildAt(i);            int position = parent.getChildAdapterposition(child);            if (position >= dataStartposition && position < dataEndposition - 1//数据项除了最后一项                    || (position == dataEndposition - 1 && mDrawLastItem)//数据项最后一项                    || (!(position >= dataStartposition && position < dataEndposition) && mDrawheaderfooter)//header&footer且可绘制                    ) {                if (orIEntation == OrIEntationHelper.VERTICAL) {                    RecyclerVIEw.LayoutParams params = (RecyclerVIEw.LayoutParams) child.getLayoutParams();                    int top = child.getBottom() + params.bottommargin;                    int bottom = top;                    mcolorDrawable.setBounds(start, top, end, bottom);                    mcolorDrawable.draw(c);                } else {                    RecyclerVIEw.LayoutParams params = (RecyclerVIEw.LayoutParams) child.getLayoutParams();                    int left = child.getRight() + params.rightmargin;                    int right = left;                    mcolorDrawable.setBounds(left, start, right, end);                    mcolorDrawable.draw(c);                }            }        }    }}

防止按键速度过快RecyclerVIEw焦点乱飞问题:

Focuslinearlayoutmanager.java

package com.example.focusdome.vIEw;import androID.content.Context;import androID.util.AttributeSet;import androID.util.Log;import androID.vIEw.VIEw;import androIDx.annotation.NonNull;import androIDx.annotation.Nullable;import androIDx.recyclervIEw.Widget.linearlayoutmanager;public class Focuslinearlayoutmanager extends linearlayoutmanager {    public Focuslinearlayoutmanager(Context context) {        super(context);    }    public Focuslinearlayoutmanager(Context context, int orIEntation, boolean reverseLayout) {        super(context, orIEntation, reverseLayout);    }    public Focuslinearlayoutmanager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {        super(context, attrs, defStyleAttr, defStyleRes);    }    @Nullable    @OverrIDe    public VIEw onInterceptFocusSearch(@NonNull VIEw focused, int direction) {        Log.v("manger","ssssss");        int currentposition = getposition(getFocusedChild());        int count = getItemCount();        int lastVisibleposition = findLastVisibleItemposition();        switch (direction){            case VIEw.FOCUS_RIGHT:                currentposition++;                break;            case VIEw.FOCUS_left:                currentposition++;                break;            case VIEw.FOCUS_DOWN:                currentposition++;                break;            case VIEw.FOCUS_UP:                currentposition++;                break;        }        if (currentposition<0||currentposition>count){            return focused;        }else {            if (currentposition>lastVisibleposition){                scrollToposition(currentposition);            }        }        return super.onInterceptFocusSearch(focused, direction);    }}

 项目地址:https://download.csdn.net/download/qq_41861266/12691503

总结

以上是内存溢出为你收集整理的Android TV 焦点控制实例全部内容,希望文章能够帮你解决Android TV 焦点控制实例所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1059501.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存