2012-08-09 18 views
6

リクエストに応じて追加ビューが追加されるリストビューがあります。これはBaseAdapterによって管理されています。更新後にスクロール位置を維持する方法はありますか?Android ListView - 更新時にトップにスクロールする

これは数回お願いしていますが、毎回同じ解決策が提示されていますが、これはリストの内容を含むArrayListを更新した後にadapter.notifyDataSetChanged();を呼び出したものです。

スクロール位置が確実に維持されるようにするにはどうすればよいですか?

+1

コードを含めてください。 –

答えて

12

アクティビティクラスでOnScrollListenerを実装し、次のコードを使用:あなたはあなたができる、その後、あなたのデータを更新するためのAsyncTaskを使用している場合

int currentFirstVisibleItem, currentVisibleItemCount, currentTotalItemCount; 
public void onScroll(AbsListView view, int firstVisibleItem, 
     int visibleItemCount, int totalItemCount) { 
    this.currentFirstVisibleItem = firstVisibleItem; 
    this.currentVisibleItemCount = visibleItemCount; 
    this.currentTotalItemCount = totalItemCount; 
} 

public void onScrollStateChanged(AbsListView view, int scrollState) { 
    this.currentScrollState = scrollState; 
    this.isScrollCompleted(); 
} 

private void isScrollCompleted() { 

    if (currentFirstVisibleItem + currentVisibleItemCount >= currentTotalItemCount) { 
     if (this.currentVisibleItemCount > 0 
       && this.currentScrollState == SCROLL_STATE_IDLE) { 

      //Do your work 
     } 
    } 
} 

をスクロール位置を維持するためにに次を含めてください:

list.setAdapter(adapter); 
list.setSelectionFromTop(currentFirstVisibleItem, 0); 

私はこれが役に立ちそうです。

+0

//あなたの仕事は何を意味しますか?それ以外に何があるでしょうか? – ajacian81

+0

//あなたの仕事は、スクロール完了時にしたいようにコードを書くことができます。例えば、Facebookのようにスクロールしてもっとデータをロードしたい場合は、ここにコードを書くことができます。 –

+0

フッターを追加してもうまくいきます...リストビューにリフレッシュのヘッダーを追加するのは何ですか?だから私に条件を与えてリストビューにヘッダを追加してください – Arun

5

私が取るアプローチは、ListView.setSelection(position)を呼び出して、更新後に希望のpositionにスクロールすることです。

どこから電話をかけるのかによって、項目が適切に配置されるようにsetSelectionに電話する前にrequestFocusFromTouchに電話する必要があります。

+0

requestFocusFromTouchへの呼び出しは、私の欠けている重要なステップでした! – Newtz

+1

YESSSSSSSSSSSもし私ができるなら、私はあなたを抱きしめるだろう。この問題を解決するのに長い時間 – Vfleitao

2

あなたはこれを試すことができます。

//Get the top position from the first visible element 
int fVisible = list.getFirstVisiblePosition(); 
View vFirst = list.getChildAt(0); 
int pos = 0; 
if (vFirst != null) pos = vFirst.getTop(); 

//Restore the position 
list.setSelectionFromTop(fVisible, pos); 
+0

残念ながら、それはうまくいきませんでした。ログを記録した後、目的の位置にスクロールした後、位置をリセットしてトップに戻ります。 – ajacian81

+0

ajacian81私が投稿した新しい解決策をチェックしてください...これが助けてくれることを祈っています... –

3

このコードは、あなたが以下のように行うことができます

// get position of listview 
int index = listView.getFirstVisiblePosition(); 
View v = listView.getChildAt(0); 
int top = (v == null) ? 0 : v.getTop(); 

// notify dataset changed or re-assign adapter here 

//re-assign the position of listview after setting the adapter again 
listView.setSelectionFromTop(index, top); 

乾杯:)

+0

完璧な、私の場合、クリックした画像をリストレイアウトで切り替える関連するビューを更新する以外に、変更されました。どうもありがとう!! – WallyHale

0

....あなたを助けます。スクロールバーを下にしてより多くのデータをロードしたい場合、いくつかの変更があります。

int currentFirstVisibleItem, currentScrollState; 
int countChange = 0; 
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 
    Log.d("Scroll", "Scrolling"); 
    this.currentFirstVisibleItem = firstVisibleItem; 
    countChange = 0;//during touching you can decide not to refresh by scroll 
} 

public void onScrollStateChanged(AbsListView view, int scrollState) { 
    Log.d("Scroll", "Changed"); 
    this.currentScrollState = scrollState; 
    if (scrollState == SCROLL_STATE_TOUCH_SCROLL) { 
     countChange = 0; 
    } 
    if (++countChange > 1) { 
     //scroll to top and release touch change=2. Simple scroll and release touch change=1 
     this.isScrollCompleted(); 
     countChange = 0; 
    } 
} 

private void isScrollCompleted() { 
    Log.d("Load", "Reload"); 
    if (currentFirstVisibleItem == 0) { 
     //Your loading go here 
    } 
} 
+0

はい、これはコードの画像ではありません。私はちょうどコードとして書くことを試みた。これはIDEのコードと同じようなものではありません。 –

関連する問題