上一篇中介绍了TV开发中的列表焦点实现
android tv列表焦点记忆实现 ,是用外部代码html" target="_blank">控制的方式实现的,比较繁琐,现在介绍用自定义RecyclerView的方式来实现,并增加了其他的功能:限制纵向和横向移出焦点,移入移出焦点的事件监听等。
代码实现如下:
import android.content.Context; import android.support.annotation.Nullable; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; import java.util.ArrayList; public class FocusKeepRecyclerView extends RecyclerView { private static final String TAG = FocusKeepRecyclerView.class.getSimpleName(); //是否可以纵向移出 private boolean mCanFocusOutVertical = true; //是否可以横向移出 private boolean mCanFocusOutHorizontal = true; //焦点移出recyclerview的事件监听 private FocusLostListener mFocusLostListener; //焦点移入recyclerview的事件监听 private FocusGainListener mFocusGainListener; //默认第一次选中第一个位置 private int mCurrentFocusPosition = 0; public FocusKeepRecyclerView(Context context) { this(context, null); } public FocusKeepRecyclerView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public FocusKeepRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); setChildrenDrawingOrderEnabled(true); setItemAnimator(null); this.setFocusable(true); } public boolean isCanFocusOutVertical() { return mCanFocusOutVertical; } public void setCanFocusOutVertical(boolean canFocusOutVertical) { mCanFocusOutVertical = canFocusOutVertical; } public boolean isCanFocusOutHorizontal() { return mCanFocusOutHorizontal; } public void setCanFocusOutHorizontal(boolean canFocusOutHorizontal) { mCanFocusOutHorizontal = canFocusOutHorizontal; } @Override public View focusSearch(int direction) { return super.focusSearch(direction); } //覆写focusSearch寻焦策略 @Override public View focusSearch(View focused, int direction) { Log.i(TAG, "focusSearch " + focused + ",direction= " + direction); View view = super.focusSearch(focused, direction); if (focused == null) { return view; } if (view != null) { //该方法返回焦点view所在的父view,如果是在recyclerview之外,就会是null.所以根据是否是null,来判断是否是移出了recyclerview View nextFocusItemView = findContainingItemView(view); if (nextFocusItemView == null) { if (!mCanFocusOutVertical && (direction == View.FOCUS_DOWN || direction == View.FOCUS_UP)) { //屏蔽焦点纵向移出recyclerview return focused; } if (!mCanFocusOutHorizontal && (direction == View.FOCUS_LEFT || direction == View.FOCUS_RIGHT)) { //屏蔽焦点横向移出recyclerview return focused; } //调用移出的监听 if (mFocusLostListener != null) { mFocusLostListener.onFocusLost(focused, direction); } return view; } } return view; } public void setFocusLostListener(FocusLostListener focusLostListener) { this.mFocusLostListener = focusLostListener; } public interface FocusLostListener { void onFocusLost(View lastFocusChild, int direction); } public void setGainFocusListener(FocusGainListener focusListener) { this.mFocusGainListener = focusListener; } public interface FocusGainListener { void onFocusGain(View child, View focued); } @Override public void requestChildFocus(View child, View focused) { Log.i(TAG, "nextchild= " + child + ",focused = " + focused); if (!hasFocus()) { //recyclerview 子view 重新获取焦点,调用移入焦点的事件监听 if (mFocusGainListener != null) { mFocusGainListener.onFocusGain(child, focused); } } super.requestChildFocus(child, focused);//执行过super.requestChildFocus之后hasFocus会变成true mCurrentFocusPosition = getChildViewHolder(child).getAdapterPosition(); Log.i(TAG,"focusPos = "+mCurrentFocusPosition); } //实现焦点记忆的关键代码 @Override public void addFocusables(ArrayList<View> views, int direction, int focusableMode) { View view = null; if (this.hasFocus() || mCurrentFocusPosition < 0 || (view = getLayoutManager().findViewByPosition(mCurrentFocusPosition)) == null) { super.addFocusables(views,direction,focusableMode); }else if(view.isFocusable()){ //将当前的view放到Focusable views列表中,再次移入焦点时会取到该view,实现焦点记忆功能 views.add(view); }else{ super.addFocusables(views,direction,focusableMode); } } /** * 控制当前焦点最后绘制,防止焦点放大后被遮挡 * 原顺序123456789,当4是focus时,绘制顺序变为123567894 * @param childCount * @param i * @return */ @Override protected int getChildDrawingOrder(int childCount, int i) { View focusedChild = getFocusedChild(); Log.i(TAG,"focusedChild ="+focusedChild); if(focusedChild== null){ return super.getChildDrawingOrder(childCount, i); }else{ int index = indexOfChild(focusedChild); Log.i(TAG, " index = " + index + ",i=" + i + ",count=" + childCount); if(i == childCount-1){ return index; } if(i<index){ return i; } return i+1; } } }
代码实现和注释说明如上。
可以直接作为一个recyclerview使用,已经具有了焦点记忆的功能了,不需要在外层增加额外的代码;要增加限制纵向和横向移出焦点,移入移出焦点的事件监听的功能,可以再调用上面的setXXXListener等方法。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
A我是Drools的新手,读过一些文档和教程,当然,我的问题有一个简单的解决方案。我使用onle规则文件和类计数器,如下所示。环境为:Wintel JDK 1.7(71),DROOLS 6.1.0 有个规矩 这是kModule 跑步的结果 我的问题是: > 为什么“反淋浴1”规则只涉及最后插入的事实?是否存在任何隐藏行为? 3、为什么在count==1的retract object Counter
问题内容: Java应该没有内存泄漏,但是仍然可能。当我的程序出现内存泄漏时,我可以修复它(我希望)。但是,当某些第三方程序包具备该功能时,我该怎么办?几乎什么都没有,除非不使用此软件包。 还有其他解决方案吗?我喜欢沙盒的想法。您被允许在某个区域内做任何您想做的事情,而您的“身体上的”没有能力打扰其他人。有没有办法为Java中的内存使用创建此类沙箱?想象一下=创建用于内存使用的沙箱,允许某些程序包
问题内容: 我想创建一个程序来模拟Unix服务器上的内存不足(OOM)情况。我创建了这个超级简单的内存消耗者: 它消耗的内存与定义的内存一样多,而现在恰好是50 GB的RAM。它按1 MB分配内存,并精确打印无法分配更多内存的点,这样我就知道它设法吃了哪个最大值。 问题是它有效。即使在具有1 GB物理内存的系统上。 当我检查顶部时,我发现该进程占用了50 GB的虚拟内存,而占用的驻留内存不到1 M
我用Selenium和C#编写了一个多线程自动化,它使用了很多Chrome浏览器(可以重复)。 我尝试使用所有内容,包括“--ingnito”、“--disable-apps ation-cache”,在打开另一个浏览器、、和。这是代码示例: 并建议我的客户通过单击按钮执行此代码来杀死所有“chromedriver.exe”进程: 但是我的客户仍然在说关闭和完成的自动化浏览器的记忆仍然存在? 有什
我想创建一个程序来模拟Unix服务器上的内存不足(OOM)情况。我创造了这个超级简单的记忆食客: 它消耗的内存与中定义的一样多,现在正好是50 问题是它是有效的。即使在具有1的系统上 当我检查top时,我看到这个过程消耗了50 系统规范:Linux内核3.16(Debian)很可能启用了Overmit(不知道如何检查),没有交换和虚拟化。
问题内容: 我有一个程序可以通过递归传递大量数据,例如1000个变量。递归将至少运行50或60次。我担心的是,由于没有足够的空间,是否有可能数据在内存位置上被覆盖,或者如果没有内存,那么我会得到一些例外,即程序内存已经用完(我没有收到这样的错误)? 是否存在错误的解决方案,因为该程序没有更多的内存并且在现有位置上被覆盖? 问题答案: 涉及两个存储区域:堆栈和堆。堆栈是保存方法调用的当前 状态 (即
问题内容: 我的代码中有一些函数,使用记忆很有意义(甚至是强制性的)。 我不想为每个功能分别手动实现。有什么办法(例如在Python中),我可以只使用注释或做其他事情,以便在需要的地方自动获得这些注释? 问题答案: Spring 3.1现在提供了一个注释,它可以做到这一点。 顾名思义,@Cacheable用于划分可缓存的方法-即将结果存储到缓存中的方法,以便在后续调用(具有相同参数)时返回缓存中的
我的想法是有一个这样的东西,您可以在其中存储以前的答案并在以后查找它们。我想这可以通过lambda表达式来完成,但我不太熟悉它们。我不太确定如何编写这个方法,希望得到一些帮助。 用这种方法能做到这一点吗?