您好,登錄后才能下訂單哦!
這篇文章主要介紹Android RecyclerView中焦點記憶封裝的示例分析,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
android tv列表焦點記憶實現 ,是用外部代碼控制的方式實現的,比較繁瑣,現在介紹用自定義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等方法。
以上是“Android RecyclerView中焦點記憶封裝的示例分析”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。