1. 程式人生 > >android ListView 重新進入後如何回到之前位置

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