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

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

Android RecyclerView的焦點(diǎn)記憶封裝

2019-12-12 01:02:42
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

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

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

代碼實(shí)現(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;  //焦點(diǎn)移出recyclerview的事件監(jiān)聽(tīng)  private FocusLostListener mFocusLostListener;  //焦點(diǎn)移入recyclerview的事件監(jiān)聽(tīng)  private FocusGainListener mFocusGainListener;  //默認(rèn)第一次選中第一個(gè)位置  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) {  //該方法返回焦點(diǎn)view所在的父view,如果是在recyclerview之外,就會(huì)是null.所以根據(jù)是否是null,來(lái)判斷是否是移出了recyclerview      View nextFocusItemView = findContainingItemView(view);      if (nextFocusItemView == null) {        if (!mCanFocusOutVertical && (direction == View.FOCUS_DOWN || direction == View.FOCUS_UP)) {          //屏蔽焦點(diǎn)縱向移出recyclerview          return focused;        }        if (!mCanFocusOutHorizontal && (direction == View.FOCUS_LEFT || direction == View.FOCUS_RIGHT)) {          //屏蔽焦點(diǎn)橫向移出recyclerview          return focused;        }       //調(diào)用移出的監(jiān)聽(tīng)        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ǎn),調(diào)用移入焦點(diǎn)的事件監(jiān)聽(tīng)      if (mFocusGainListener != null) {        mFocusGainListener.onFocusGain(child, focused);      }    }    super.requestChildFocus(child, focused);//執(zhí)行過(guò)super.requestChildFocus之后hasFocus會(huì)變成true    mCurrentFocusPosition = getChildViewHolder(child).getAdapterPosition();    Log.i(TAG,"focusPos = "+mCurrentFocusPosition);  } //實(shí)現(xiàn)焦點(diǎn)記憶的關(guā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()){//將當(dāng)前的view放到Focusable views列表中,再次移入焦點(diǎn)時(shí)會(huì)取到該view,實(shí)現(xiàn)焦點(diǎn)記憶功能      views.add(view);    }else{      super.addFocusables(views,direction,focusableMode);    }  }    /**   * 控制當(dāng)前焦點(diǎn)最后繪制,防止焦點(diǎn)放大后被遮擋   * 原順序123456789,當(dāng)4是focus時(shí),繪制順序變?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;    }  }}

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

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

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 静乐县| 自贡市| 新巴尔虎左旗| 鹤岗市| 蒲城县| 商都县| 青田县| 客服| 安西县| 长垣县| 大同市| 阿瓦提县| 车险| 布尔津县| 如东县| 上饶县| 祁东县| 盐津县| 岚皋县| 衡南县| 金坛市| 嫩江县| 屏边| 应城市| 汾阳市| 雷州市| 陇西县| 张北县| 桂东县| 富平县| 江津市| 杂多县| 杭锦后旗| 普宁市| 周宁县| 漯河市| 麦盖提县| 平度市| 柞水县| 江源县| 安远县|