21

アダプターのデータを変更するときに、リストビューのスクロール位置を維持するのに少し問題があります。

私が現在行っているのは、ListFragmentのにカスタムArrayAdapter(オーバーライドされたonCreategetViewメソッドを使用)を作成し、それをそのリストに割り当てることです。

mListAdapter = new CustomListAdapter(getActivity());
mListAdapter.setNotifyOnChange(false);
setListAdapter(mListAdapter);

次に、すべてを定期的にフェッチするローダーから新しいデータを受け取ると、onLoadFinishedコールバックでこれを行います。

mListAdapter.clear();
mListAdapter.addAll(data.items);
mListAdapter.notifyDataSetChanged();

問題は、呼び出すとclear()リストビューのスクロール位置がリセットされることです。その呼び出しを削除すると、位置は保持されますが、明らかに古いアイテムがリストに残ります。

これを行うための適切な方法は何ですか?

4

4 に答える 4

34

ご指摘のとおり、「clear()」を呼び出すと、位置が一番上にリセットされます。

スクロール位置などをいじるのは、これを機能させるためのちょっとしたハックです。

CustomListAdapter が ArrayAdapter からサブクラス化されている場合、これが問題になる可能性があります。

clear() の呼び出しは、'notifyDataSetChanged()' を呼び出します。これを防ぐことができます:

mListAdapter.setNotifyOnChange(false); // Prevents 'clear()' from clearing/resetting the listview
mListAdapter.clear();
mListAdapter.addAll(data.items);
// note that a call to notifyDataSetChanged() implicitly sets the setNotifyOnChange back to 'true'!
// That's why the call 'setNotifyOnChange(false) should be called first every time (see call before 'clear()').
mListAdapter.notifyDataSetChanged(); 

私はこれを自分で試したことはありませんが、試してみてください:)

于 2013-02-06T00:30:06.057 に答える
6

チェックアウト: ListView に戻るときにスクロール位置を維持/保存/復元する

これを使用して、.clear()、.addAll()、および を呼び出す前に ListView の位置を保存します。notifyDataSetChanged()。

int index = mList.getFirstVisiblePosition();
View v = mList.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();

ListView アダプターを更新した後、Listview の項目が変更され、新しい位置が設定されます。

mList.setSelectionFromTop(index, top);

基本的に、位置を保存してそこにスクロールし、ListView の状態またはアプリケーション全体の状態を保存できます。

その他の役立つリンク:

位置の保存: Android で ListView の位置を保存および復元する方法

状態の保存: Android ListView の y 位置

よろしく、

これが役立つかどうか教えてください!

于 2013-02-05T23:13:02.447 に答える
-1

Expandable/List アダプターに、このメソッドを入れます

public void refresh(List<MyDataClass> dataList) {
    mDataList.clear();
    mDataList.addAll(events);
    notifyDataSetChanged();
}

そして、リストを更新したいアクティビティから、このコードを入れます

if (mDataListView.getAdapter() == null) {
    MyDataAdapter myDataAdapter = new MyDataAdapter(mContext, dataList);
    mDataListView.setAdapter(myDataAdapter);
} else {
    ((MyDataAdapter)mDataListView.getAdapter()).refresh(dataList);
}

Expandable List Viewの場合、mDataListView.getAdapter()の代わりに mDataListView.getExpandableListAdapter( )を使用します。

于 2013-09-30T11:51:34.123 に答える