首先上实例:
项目工程文件:
界面布局:
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 焦点控制实例所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)