国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android RecyclerView的焦點記憶封裝

2019-10-22 18:13:12
字體:
來源:轉載
供稿:網(wǎng)友

上一篇中介紹了TV開發(fā)中的列表焦點實現(xiàn)

android tv列表焦點記憶實現(xiàn) ,是用外部代碼控制的方式實現(xiàn)的,比較繁瑣,現(xiàn)在介紹用自定義RecyclerView的方式來實現(xiàn),并增加了其他的功能:限制縱向和橫向移出焦點,移入移出焦點的事件監(jiān)聽等。

代碼實現(xiàn)如下:

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的事件監(jiān)聽  private FocusLostListener mFocusLostListener;  //焦點移入recyclerview的事件監(jiān)聽  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.所以根據(jù)是否是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;        }       //調(diào)用移出的監(jiān)聽        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 重新獲取焦點,調(diào)用移入焦點的事件監(jiān)聽      if (mFocusGainListener != null) {        mFocusGainListener.onFocusGain(child, focused);      }    }    super.requestChildFocus(child, focused);//執(zhí)行過super.requestChildFocus之后hasFocus會變成true    mCurrentFocusPosition = getChildViewHolder(child).getAdapterPosition();    Log.i(TAG,"focusPos = "+mCurrentFocusPosition);  } //實現(xiàn)焦點記憶的關鍵代碼  @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,實現(xiàn)焦點記憶功能      views.add(view);    }else{      super.addFocusables(views,direction,focusableMode);    }  }    /**   * 控制當前焦點最后繪制,防止焦點放大后被遮擋   * 原順序123456789,當4是focus時,繪制順序變?yōu)?23567894   * @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;    }  }}

代碼實現(xiàn)和注釋說明如上。

可以直接作為一個recyclerview使用,已經(jīng)具有了焦點記憶的功能了,不需要在外層增加額外的代碼;要增加限制縱向和橫向移出焦點,移入移出焦點的事件監(jiān)聽的功能,可以再調(diào)用上面的setXXXListener等方法。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關教程知識閱讀請移步到Android開發(fā)頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 贡嘎县| 辽阳县| 长岭县| 航空| 玉田县| 弥勒县| 鹤壁市| 安仁县| 泰和县| 德昌县| 沙雅县| 腾冲县| 宜兰县| 朝阳县| 同江市| 康平县| 调兵山市| 宁津县| 桑植县| 含山县| 怀来县| 贡觉县| 大兴区| 安达市| 威远县| 图们市| 商洛市| 昌黎县| 武清区| 光泽县| 隆回县| 定结县| 保康县| 宁远县| 营口市| 英德市| 河间市| 准格尔旗| 班玛县| 乌兰浩特市| 响水县|