RecyclerView焦点跳转BUG优化




我们把RecyclerView写成GridView样式,并把RecyclerView的item写成focusable并且有焦点框的时候,我们用焦点滚动RecyclerView的时候会发现RecyclerView的焦点跳转有bug,跟我们想要的焦点跳转规则不一致,会出现的BUG如下图:

黑色方框代表屏幕,我们从左上角的一个item往下按焦点的时候,当需要加载新的一行的时候焦点却跑到了新的一行的最后一个item上面了,(如图,本来是item1获得焦点的,结果跑到item2上面了)。

   这是RecyclerView的一个BUG,记得RecyclerView刚出来的时候滚动都还有点卡顿,到了现在滚动起来还是非常流畅的,比较一个全新的艺术般的空间是需要时间来沉淀的,这个BUG我们可以重写GridLayoutManger来解决。直接看代码:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.wasu.cs.widget;  
  2.   
  3. import android.content.Context;  
  4. import android.support.v7.widget.GridLayoutManager;  
  5. import android.support.v7.widget.RecyclerView;  
  6. import android.util.AttributeSet;  
  7. import android.view.View;  
  8.   
  9. /** 
  10.  * 自定义GridLayoutManager,修改RecyelerView焦点乱跳的BUG 
  11.  * Created by Danxingxi on 2016/4/1. 
  12.  */  
  13. public class FocusGridLayoutManager extends GridLayoutManager {  
  14.   
  15.   
  16.     /** 
  17.      * Constructor used when layout manager is set in XML by RecyclerView attribute 
  18.      * "layoutManager". If spanCount is not specified in the XML, it defaults to a 
  19.      * single column. 
  20.      * 
  21.      * @param context 
  22.      * @param attrs 
  23.      * @param defStyleAttr 
  24.      * @param defStyleRes 
  25.      * @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_spanCount 
  26.      */  
  27.     public FocusGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {  
  28.         super(context, attrs, defStyleAttr, defStyleRes);  
  29.     }  
  30.   
  31.     /** 
  32.      * Creates a vertical GridLayoutManager 
  33.      * 
  34.      * @param context   Current context, will be used to access resources. 
  35.      * @param spanCount The number of columns in the grid 
  36.      */  
  37.     public FocusGridLayoutManager(Context context, int spanCount) {  
  38.         super(context, spanCount);  
  39.     }  
  40.   
  41.     /** 
  42.      * @param context       Current context, will be used to access resources. 
  43.      * @param spanCount     The number of columns or rows in the grid 
  44.      * @param orientation   Layout orientation. Should be {@link #HORIZONTAL} or {@link 
  45.      *                      #VERTICAL}. 
  46.      * @param reverseLayout When set to true, layouts from end to start. 
  47.      */  
  48.     public FocusGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {  
  49.         super(context, spanCount, orientation, reverseLayout);  
  50.     }  
  51.   
  52.     /** 
  53.      * Return the current number of child views attached to the parent RecyclerView. 
  54.      * This does not include child views that were temporarily detached and/or scrapped. 
  55.      * 
  56.      * @return Number of attached children 
  57.      */  
  58.     @Override  
  59.     public int getChildCount() {  
  60.         return super.getChildCount();  
  61.     }  
  62.   
  63.     /** 
  64.      * Return the child view at the given index 
  65.      * 
  66.      * @param index Index of child to return 
  67.      * @return Child view at index 
  68.      */  
  69.     @Override  
  70.     public View getChildAt(int index) {  
  71.         return super.getChildAt(index);  
  72.     }  
  73.   
  74.     /** 
  75.      * Returns the number of items in the adapter bound to the parent RecyclerView. 
  76.      * @return The number of items in the bound adapter 
  77.      */  
  78.     @Override  
  79.     public int getItemCount() {  
  80.         return super.getItemCount();  
  81.     }  
  82.   
  83.     /** 
  84.      * Returns the item View which has or contains focus. 
  85.      * 
  86.      * @return A direct child of RecyclerView which has focus or contains the focused child. 
  87.      */  
  88.     @Override  
  89.     public View getFocusedChild() {  
  90.         return super.getFocusedChild();  
  91.     }  
  92.   
  93.     /** 
  94.      * Returns the adapter position of the item represented by the given View. This does not 
  95.      * contain any adapter changes that might have happened after the last layout. 
  96.      * 
  97.      * @param view The view to query 
  98.      * @return The adapter position of the item which is rendered by this View. 
  99.      */  
  100.     @Override  
  101.     public int getPosition(View view) {  
  102.         return super.getPosition(view);  
  103.     }  
  104.   
  105.     /** 
  106.      * 获取列数 
  107.      * @return 
  108.      */  
  109.     @Override  
  110.     public int getSpanCount() {  
  111.         return super.getSpanCount();  
  112.     }  
  113.   
  114.     /** 
  115.      * Called when searching for a focusable view in the given direction has failed for the current content of the RecyclerView. 
  116.      * This is the LayoutManager's opportunity to populate views in the given direction to fulfill the request if it can. 
  117.      * The LayoutManager should attach and return the view to be focused. The default implementation returns null. 
  118.      * 防止当recyclerview上下滚动的时候焦点乱跳 
  119.      * @param focused 
  120.      * @param focusDirection 
  121.      * @param recycler 
  122.      * @param state 
  123.      * @return 
  124.      */  
  125.     @Override  
  126.     public View onFocusSearchFailed(View focused, int focusDirection, RecyclerView.Recycler recycler, RecyclerView.State state) {  
  127.   
  128.         // Need to be called in order to layout new row/column  
  129.         View nextFocus = super.onFocusSearchFailed(focused, focusDirection, recycler, state);  
  130.   
  131.         if (nextFocus == null) {  
  132.             return null;  
  133.         }  
  134.         /** 
  135.          * 获取当前焦点的位置 
  136.          */  
  137.         int fromPos = getPosition(focused);  
  138.         /** 
  139.          * 获取我们希望的下一个焦点的位置 
  140.          */  
  141.         int nextPos = getNextViewPos(fromPos, focusDirection);  
  142.   
  143.         return findViewByPosition(nextPos);  
  144.   
  145.     }  
  146.   
  147.     /** 
  148.      * Manually detect next view to focus. 
  149.      * 
  150.      * @param fromPos from what position start to seek. 
  151.      * @param direction in what direction start to seek. Your regular {@code View.FOCUS_*}. 
  152.      * @return adapter position of next view to focus. May be equal to {@code fromPos}. 
  153. <span class="comment" style="margin: 0px; padding: 0px; border: none;%2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值