轉載請标明出處:
http://blog.csdn.net/tyzlmjj/article/details/49227601
本文出自:【M家傑的部落格】
概述
RecyclerView在安卓開發中非常實用,而且簡單易用,但是在實際開發中一直有一個問題困擾着我,就是定位問題,實際的項目中總是會遇到這樣的需求:檢索RecyclerView的某一項(各個項的高度不确定),然後定位這一項,将它顯示在頂部。用RecyclerView的預設移動的方法并不能實作這一點(個人感覺官方可能出于性能考慮才不實作這一點)。這篇部落格就講解下我個人是如何實作這個需求的。
Demo示範
敲代碼前的思考
RecyclerView提供的用于控制移動的方法有2個
-
scrollToPosition(int)
這個方法的作用是顯示指定項,就是把你想置頂的項顯示出來,但是在螢幕的什麼位置是不管的,隻要那一項現在看得到了,那它就罷工了!
-
scrollBy(int x,int y)
這個方法是自己去控制移動的距離,機關應該是像素。
使用scrollToPosition時,移動到前面的項時,它預設會将要顯示的項置頂,但是移動到後面的項時,位置就說不好了(看它心情!)一般會顯示在最後一個。用過的應該都有所了解。
使用scrollBy時就需要自己計算高度或者寬度。在動态的布局中且各項樣式高度可能都不一樣的情況下,自己計算高度是很有難度的。
上面說了這麼多廢話,結論就是這2個方法都不能很好解決問題,但是,當他們2個結合使用的時候,我們的問題就變的好解決很多了!
思路是:先用scrollToPosition,将要置頂的項先移動顯示出來,然後計算這一項離頂部的距離,用scrollBy完成最後的100米!
關鍵代碼
先傳入要置頂第幾項,然後區分情況處理
private void moveToPosition(int n) {
//先從RecyclerView的LayoutManager中擷取第一項和最後一項的Position
int firstItem = mLinearLayoutManager.findFirstVisibleItemPosition();
int lastItem = mLinearLayoutManager.findLastVisibleItemPosition();
//然後區分情況
if (n <= firstItem ){
//當要置頂的項在目前顯示的第一個項的前面時
mRecyclerView.scrollToPosition(n);
}else if ( n <= lastItem ){
//當要置頂的項已經在螢幕上顯示時
int top = mRecyclerView.getChildAt(n - firstItem).getTop();
mRecyclerView.scrollBy(, top);
}else{
//當要置頂的項在目前顯示的最後一項的後面時
mRecyclerView.scrollToPosition(n);
//這裡這個變量是用在RecyclerView滾動監聽裡面的
move = true;
}
}
RecyclerView滾動監聽
class RecyclerViewListener extends RecyclerView.OnScrollListener{
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
//在這裡進行第二次滾動(最後的100米!)
if (move ){
move = false;
//擷取要置頂的項在目前螢幕的位置,mIndex是記錄的要置頂項在RecyclerView中的位置
int n = mIndex - mLinearLayoutManager.findFirstVisibleItemPosition();
if ( <= n && n < mRecyclerView.getChildCount()){
//擷取要置頂的項頂部離RecyclerView頂部的距離
int top = mRecyclerView.getChildAt(n).getTop();
//最後的移動
mRecyclerView.scrollBy(, top);
}
}
}
}
Demo下載下傳
[CSDN]
[GitHub]