好久沒有寫東西了响驴,一直想寫點啥但也不知道寫啥,糾結(jié)到今天決定大膽的寫一篇小技巧類的文章撕蔼,之前是想繼續(xù)寫IM來著豁鲤,只是服務(wù)器掛了又有各種事情的困擾。鲸沮。琳骡。好吧,以后一定堅持下去K夏纭i购拧!
背景:之前做過一款包含類似朋友圈功能的應(yīng)用怒坯,細心的朋友會發(fā)現(xiàn)當(dāng)滑動朋友圈列表查看朋友們的各種曬圖之后直接返回到發(fā)現(xiàn)界面炫狱,這時候再次進入朋友圈列表會直接定位到上次查看的地方,當(dāng)時我就想到了采用singleInstance這種啟動模式剔猿,后來發(fā)現(xiàn)這種模式不行毕荐,會造成身體各種不適(比如嘔吐啊腹瀉啊之類的),開個玩笑O(∩_∩)O哈哈~
總之翻來覆去輾轉(zhuǎn)反側(cè)以至于側(cè)夜未眠之后就想到了列表定位的方法輕松的實現(xiàn)了艳馒,當(dāng)然和IOS的同事溝通后發(fā)現(xiàn)他們實現(xiàn)起來是真心的方便憎亚,直接設(shè)置單例并保存在內(nèi)存中直到應(yīng)用退出都會身體倍棒吃嘛嘛香员寇,真真是郁了個悶的。
當(dāng)時大家普遍還在用ListView第美,所以本文采用的是ListView的實現(xiàn)方式蝶锋,下次可能會再寫一篇使用RecycleView實現(xiàn)的,畢竟是主流了嘛(__) 嘻嘻……
使用RecycleView定位的可以看這篇
android RecyclerView實現(xiàn)列表定位
一不小心就說的有點多了什往,直接進入正題吧:
先上個圖:
先對ListView注冊監(jiān)聽扳缕,使用API提供的OnScrollListener來監(jiān)聽滾動事件mListView.setOnScrollListener(this)
這里使用最簡單的ArrayAdapter
作為列表的適配器
List<String> lists = new ArrayList<>();
for (int i = 0; i < 50; i++) {
lists.add("我是item" + i);
}
String[] datas = lists.toArray(new String[lists.size()]);
ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
android.R.layout.simple_list_item_1, datas);
為了方便,這里直接使用List.toArray把List轉(zhuǎn)換為數(shù)組
注冊監(jiān)聽后覆寫了兩種方法
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
我們在onScrollStateChanged這里獲取列表滑動后當(dāng)前顯示在屏幕上的第一個position
然后獲取當(dāng)前顯示在屏幕中的第一個item view
注意:這個getChildAt(0)指的不是列表中的第一個item别威,而是當(dāng)前顯示在屏幕上的第一個可見的item躯舔,主要獲取這個item與父控件也即ListView的頂部距離
通過SharedPreferences把這兩個值保存起來
到這里基本就大功告成了,設(shè)置adapter后獲取這兩個保存的值
最后調(diào)用listview提供的setSelectionFromTop這個方法就能完美實現(xiàn)啦
這里要剖析下它和setSelection(int position)的區(qū)別:
setSelection的內(nèi)部也是調(diào)用了setSelectionFromTop這個方法省古,只不過
y值傳了0
調(diào)用這個方法后它會直接找到設(shè)置的position并定位粥庄,不過頂部的距離為0,也就是說上次滾動后只要當(dāng)前屏幕內(nèi)可見的第一個position的item露出了一點豺妓,再次進入也會把它全部顯示出來惜互,setSelectionFromTop的源碼如下:
這個方法內(nèi)主要做的事情就是查找position計算頂部偏移量,然后調(diào)用requestLayout()這個方法重新調(diào)用onMeasure和Onlayout重新設(shè)置自己的位置琳拭,這樣就能做到精準(zhǔn)確定上次瀏覽的位置了训堆。