RecycleView疑難雜症和技巧(一)

一、用ViewPager+Fragment佈局界面,Fragment裏面使用recyclerView來進行佈局,當RecycleView滑動到某個位置時,再切換到其他Fragment,然後再切換回來,RecycleView會自己跳到頂部。


解決辦法:通過查找相關資料發現,RecyclerView的 focusableOnTouchMode屬性默認是true,所以ViewPager切換時recyclerView自動獲得焦點就滾動到頭部。

網上的解決方法1、將RecyclerView上面的控件的設置android:focusableInTouchMode="true",或者再加上 android:focusable="true"。

網上的解決方法2、在scrollview第一個子控件里加上
android:focusable="true"
android:focusableInTouchMode="true" 

網上的解決方法3、將recyclerView上面的控件的設置android:descendantFocusability="blocksDescendants"。

該屬性是當一個view獲取焦點時,定義viewGroup和其子控件兩者之間的關係。
屬性的值有三種:
        beforeDescendants:viewgroup會優先其子類控件而獲取到焦點
        afterDescendants:viewgroup只有當其子類控件不需要獲取焦點時才獲取焦點
        blocksDescendants:viewgroup會覆蓋子類控件而直接獲得焦點

以上幾種方法,經過使用,並不能解決我項目中的問題,可能有些佈局情況適用。後來經過摸索,查找資料,找到了

最終的解決方案:

1.首先定義兩個成員變量:
private int lastPosition = 0;//位置 private int lastOffset = 0;//偏移量

2.在 OnScrollListener,onScrollStateChanged()裏添加:
rvHomeMain.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
View topView = layoutManager.getChildAt(0); //獲取可視的第一個view
lastOffset = topView.getTop(); //獲取與該view的頂部的偏移量
lastPosition = layoutManager.getPosition(topView); //得到該View的數組位置
}
});


3.當離開當前Fragment,再次回來的時候調用
@Override
public void onStart() {
super.onStart();
layoutManager.scrollToPositionWithOffset(lastPosition, lastOffset);
}
這樣RecycleView就能恢復到離開時的位置。然後新的問題出現了,當回到原來的位置時,經過幾秒鐘之後,RecycleView又跳轉到了頂部。

查看Fragment的生命週期:
切換回本身的Fragment會打印的方法:
11-29 14:33:55.820: D/AppListFragment(7649): onCreateView
11-29 14:33:55.825: D/AppListFragment(7649): onActivityCreated
11-29 14:33:55.825: D/AppListFragment(7649): onStart
11-29 14:33:55.825: D/AppListFragment(7649): onResume

RecycleView在設置數據的時候又獲取到了焦點,解決辦法,爲Fragment佈局中,爲RecycleView的最外層控件設置ID,並在代碼中得到控件,然後在Fragment的onActivityCreated中調用來奪得焦點(最好放到onActivityCreated最後面)
relativeLayout.setFocusableInTouchMode(true);
relativeLayout.setFocusable(true);
relativeLayout.requestFocus();

最後問題成功解決。

二、RecycleView判斷是否滑動到底部

public static boolean isSlideToBottom(RecyclerView recyclerView) {    
   if (recyclerView == null) return false; 
   if (recyclerView.computeVerticalScrollExtent() + recyclerView.computeVerticalScrollOffset() 
        >= recyclerView.computeVerticalScrollRange())   
     return true;  
   return false;
}

三、RecycleView跳轉至頂部

public static void MoveToPosition(LinearLayoutManager manager, RecyclerView mRecyclerView, int n) {
int firstItem = manager.findFirstVisibleItemPosition();
int lastItem = manager.findLastVisibleItemPosition();
if (n <= firstItem) {
mRecyclerView.scrollToPosition(n);
} else if (n <= lastItem) {
int top = mRecyclerView.getChildAt(n - firstItem).getTop();
mRecyclerView.scrollBy(0, top);
} else {
mRecyclerView.scrollToPosition(n);
}
}

三、ScrollView中嵌套recycleView 出現的子Item不顯示,顯示不全,終極解決方案





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章