android ListView 重新進入後如何回到之前位置
大家有沒有遇到這樣的情況,在某個頁面的ListView點選Item跳轉後,再返回時還是回到了起始位置,而不是跳轉之前滑動後的位置,不僅是跳轉,點選back鍵或者退出應用,也是如此。(如圖,我將listview滑動到14時,分別點選back或退出,再進入時,listview又顯示到0了)
雖然不是大問題,但是多少會影響使用者體驗。那麼如何改進這個問題呢,我們先看一下修改的的效果:
當我們點選跳轉、回退或退出後,再進入時,listview會預設從第一條資料載入。那麼我們在做這些操作之前是否可以記住滑動的位置呢,並且把它們儲存起來,下次重新載入時就可以直接從儲存的位置處載入。
一、獲得listview滑動後第一條Item的位置
listview有個監聽事件叫做setOnScrollListener();
我們重寫它的onScrollStateChanged()方法
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
//當我們停止滑動後,獲得listview可視區域的第一條item的Position if(scrollState==OnScrollListener.SCROLL_STATE_IDLE){ int firstPosition=lv.getFirstVisiblePosition(); }
//那麼下面這兩句又是什麼鬼
View v=lv.getChildAt(0);
int top=(v==null)?0:v.getTop();
}
1、 View v=lv.getChildAt(0);//獲取當前可視區域指定位置的view,這裡傳0,所以獲取的是第一條
getChildAt() 原始碼
/**//返回指定位置的view * Returns the view at the specified position in the group. * * @param index the position at which to get the view from * @return the view at the specified position or null if the position * does not exist within the group */ public View getChildAt(int index) { if (index < 0 || index >= mChildrenCount) { return null; } return mChildren[index]; }
2、int top=(v==null)?0:v.getTop(); //獲得距離view頂部的值(畫素)
v.getTop() 原始碼
<span style="color:#330033;"> /** <span style="font-family: Simsun; font-size: 14px; line-height: 24px; background-color: rgb(240, 240, 240);">相對應父控制元件的top位置,單位為畫素,即頭部到父控制元件的距離</span>
* Top position of this view relative to its parent.
*
* @return The top of this view, in pixels.
*/
@ViewDebug.CapturedViewProperty
public final int getTop() {
return mTop;
}</span>
將v.getTop()返回的畫素值轉換為dp,在滑動過程中即可看到dp值的變化,當它滑動到幾乎離開超出螢幕時,即可看到它的值和我們Item設定的高度是一個值。此步省略。。。
3、將前兩步獲取的兩個值,利用SharePreference儲存。
SharedPreferences spsp=getPreferences(MODE_PRIVATE);
Editor editor=sp.edit();
editor.putInt("firstPosition", firstPosition);
editor.putInt("top", top);
editor.commit();
4、下次重新載入時,在onResume()方法裡將儲存的值取出來。
firstPosition=sp.getInt("firstPosition", 0);
top=sp.getInt("top", 0);
if(firstPosition!=0&&top!=0){
//將listview通過取出的值直接顯示到指定位置
lv.setSelectionFromTop(firstPosition, top);
}
setSelectFromTop(); 原始碼
/** 設定選擇的Item和到listview頂部邊緣的畫素距離
* Sets the selected item and positions the selection y pixels from the top edge
* of the ListView. (If in touch mode, the item will not be selected but it will
* still be positioned appropriately.)
*
* @param position Index (starting at 0) of the data item to be selected.
* @param y The distance from the top edge of the ListView (plus padding) that the
* item will be positioned.
*/
public void setSelectionFromTop(int position, int y) {
if (mAdapter == null) {
return;
}
if (!isInTouchMode()) {
position = lookForSelectablePosition(position, true);
if (position >= 0) {
setNextSelectedPositionInt(position);
}
} else {
mResurrectToPosition = position;
}
if (position >= 0) {
mLayoutMode = LAYOUT_SPECIFIC;
mSpecificTop = mListPadding.top + y;
if (mNeedSync) {
mSyncPosition = position;
mSyncRowId = mAdapter.getItemId(position);
}
if (mPositionScroller != null) {
mPositionScroller.stop();
}
requestLayout();
}
}
至此,我們分析完了,下面請看全部程式碼:
佈局檔案比較簡單,就不展示了,MainActivity裡一個listview, item裡一個textvew
public class MainActivity extends Activity implements OnScrollListener{
private ListView lv;
private ArrayAdapter<String> adapter;
private List<String>list; //資料
private int firstPosition; //滑動以後的可見的第一條資料
private int top;//滑動以後的第一條item的可見部分距離top的畫素值
private SharedPreferences sp;//偏好設定
private Editor editor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
initDatas();
registerListener();
}
@Override
protected void onResume() {
super.onResume();
firstPosition=sp.getInt("firstPosition", 0);
top=sp.getInt("top", 0);
if(firstPosition!=0&&top!=0){
lv.setSelectionFromTop(firstPosition, top);
}
}
private void initViews() {
lv=(ListView) findViewById(R.id.lv);
sp=getPreferences(MODE_PRIVATE);
editor=sp.edit();
}
private void initDatas() {
list=new ArrayList<String>();
for(int i=0;i<50;i++){
list.add(String.valueOf(i));
}
adapter=new ArrayAdapter<>(this, R.layout.item, R.id.tv_name, list);
lv.setAdapter(adapter);
}
private void registerListener() {
lv.setOnScrollListener(this);
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if(scrollState==OnScrollListener.SCROLL_STATE_IDLE){
firstPosition=lv.getFirstVisiblePosition();
}
View v=lv.getChildAt(0);
top=v.getTop();
editor.putInt("firstPosition", firstPosition);
editor.putInt("top", top);
editor.commit();
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
}
最後做一個總結:
1、每次滑動以後,都記錄listview第一個item的position以及view頂部距離父控制元件頂部的值
2、將記錄的值進行儲存,可以用SharePreference
3、下次重新載入時,在onResume()方法裡進行取值,並將取出的值傳入listview.setSelectionFromTop(int,int)
相關推薦
android ListView 重新進入後如何回到之前位置
大家有沒有遇到這樣的情況,在某個頁面的ListView點選Item跳轉後,再返回時還是回到了起始位置,而不是跳轉之前滑動後的位置,不僅是跳轉,點選back鍵或者退出應用,也是如此。(如
android ListView資料變動後保持螢幕位置不變(類似QQ對話列表)
在網上找的所謂三種方法都不靠譜,比如在onScrollStateChanged事件中用lst_threads.getScaleX()獲取最後位置,不知道為何我除錯時在if (scrollState == OnScrollListener.SCROLL_S
Android: ListView 和重寫後 MyListView 的簡單使用
什麼是 ListView ?它有什麼用? 如這個頁面,多個新聞資訊:,一個個在xml寫是不可能的! 所以,我們需要用ListView迴圈寫! 一個LinearLayout 佈局中, 就一個圖片,一個標題,一個時間,一個評論數量!是不是很少啊? 一、普通的ListVi
android listview直接定位到某一行位置
如何讓listview載入完成後,直接定位到某一行? 直接用listview.setSelection(int position); adapter.notifyDataSetInvalidated();//通知adapter資料有變化 lstAjap.setSe
ViewPager+Fragment+ListView重新載入後資料來源重複問題的解決方法
今天在專案中遇到了一個問題,我的主頁Activity是以ViewPager+Fragment進行構建的,其中有兩個Fragment又包含了ListView,正常情況下這兩個Fragment的介面如下: 但是當我從主頁Activity跳轉到另一個Activi
Android listview載入資料後沒有立即重新整理的解決辦法
最近用到listview顯示從伺服器拉取回來的json資料,主要是圖片和文字資源。 Listview在載入完資料後,當我們需要ListView進行重新整理的時候,我們需要呼叫Adapter.
Android App首次安裝完成後在安裝介面直接開啟應用,再按home鍵返回桌面,從桌面圖示重新進入app,返回不到之前的介面問題
概述 在做專案的時候遇到了,Android App首次安裝完成後在安裝介面直接開啟應用,再按home鍵返回桌面,從桌面圖示重新進入app,返回不到之前介面的問題;然而有一次完全退出應用後,這個問題就會消失。然後各種檢查程式碼覺得都沒有問題,後面通過對任務棧的實
vue+webpack專案在iOS微信端偶爾出現白屏,重新整理又能重新進入的解決方案,在Android上不會出現
問題描述:微信公眾號內部的專案,我使用的是vue+webpack的方式,路徑配置正確的情況下,在Chrome上執行正常,執行npm run build放在測試伺服器上,配置好相應入口,通過微信訪問,在Android機
TOMCAT在eclipse上重新部署後就會刪除之前的圖片資源解決
1.首先在tomcat的server.xml 中的host 新增 <Context docBase="F:\images" reloadable="true" debug="0" path="/img"/> 新增圖片對映到其餘的碟符
【Android】幾個應用重新進入相關的屬性
android:clearTaskOnLaunch=”true” 當重新launch這個task的時候(當通過桌面重新進入這個應用) 會清理帶這個屬性的activity 這個屬性必須在這個task的根Activity(不是棧底,是進入而是這個應用的第一個acitivt
網頁重新整理或者重新載入後滾動條的位置不變
<script type="text/javascript"> window.onbeforeunload = function(){ var scrollPos; if (typeof window.pageYOffset !=
Listview非同步載入圖片後獲得對應位置的Imageview的方法
在Listview非同步載入網路圖片時,可在listview adapter的getview中為Imageview設定Tag(Tag為該圖片的Url,唯一),然後當載入完圖片時,可通過Listview的findViewByTag方法通過Imageview: ImageView ima
Android整合支付寶“建立交易異常,請重新建立後付款”問題
這個問題一般是公私鑰不匹配問題,但是由於程式猿一般沒有許可權去修改支付寶賬號的應用以及配置,導致一些重要建立流程我們並不是很清晰,遇到問題也很難去排查,今天藉著這個問題,將建立流程與步驟在做一下講述,算是對之前文章的一個補充。 步驟1:建立應用 這
android listview拖拽,拖動item 改變位置
在packages/apps/Music/src/touchIncepter.java中 該類提供了listview的拖動效果,並提供介面,在程式介面中實現資料的交換即可。 package com.and.DragListvie
解決在安裝完成CentOS 6.5 進行重新引導後,進入輸入使用者名稱和密碼介面登陸不成功的問題。(進入單使用者模式進行修改密碼)
問題所在: 剛開始使用的是 主機名登陸系統,失敗,後來又換成使用者名稱 : root登陸依然失敗。糾結半天。 看到提示:Login incorrect 明顯密碼與賬戶名不正確。 然後開始著手修改密碼: 首先要先進入單使用者模式: CentOS 6 重新啟動後在
Android應用程序升級後自動進入新版本
在新版本中建立一個Receiver接收手機應用的安裝和解除安裝(可以監聽到舊版本的解除安裝) package com.justsy.lpi.receiver; import android.content.BroadcastReceiver; import
Android listview增加條目時自動回滾到最後一行
當listview條目增加時,自動回滾到最後一條 listView.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL); 在xml檔
android ListView 仿IOS 回彈效果
最近看IOS的下拉效果感覺很不錯,當拉倒最上面和最下面的時候繼續拉動會有緩衝,想在android裡面也做一個,到網上到處找,沒有找到好的方法,據說android新的API對ListView有這樣的支援,感覺不是特別好用。 自己利用scroller實現了一下,廢話不多說了直接
Android ListView滑動回彈——overScrollBy
註解 /** * Scroll the view with standard behavior for scrolling beyond the normal * content boundaries. Views that call this met
實現類似於QQ空間相簿的點選圖片放大,再點後縮小回原來位置
package com.kale.gridviewanimtest; import android.graphics.Point; import android.graphics.Rect; import android.view.View; import android.view.Vie