無限スクロールリストビューを実装しようとしていますが、notifyDataSetChanged()
を呼び出すと、リスト全体が更新され、スクロール位置が先頭に戻ります。
これは通常の動作ですか?更新せずに追加されたアイテムを単純に追加し、スクロール位置を維持するにはどうすればよいですか?
このような動作は正常ではありません。あなたのコードを見ることなく、私は以下を提案することができます:
1)UIスレッドからnotifyDataSetChanged()
を呼び出していません。正しい方法:
_runOnUiThread(new Runnable() {
public void run() {
adapter.notifyDataSetChanged();
}
});
_
2)誤ってadapter.notifyDataSetInvalidated();
を呼び出しているかどうか
3)アダプタでadapter.notifyDataSetChanged();
メソッドをオーバーライドし、トップに移動するための命令を追加しました
4)リストを使用してアダプターにデータを入力している場合-毎回新しいリストを提供するため、アダプターの設定が更新されます。常に同じリストを提供する必要があります。ただし、必要なだけ変更できます。リストをリセットする場合は、list = new ArrayList();
の代わりに_list.clear
_を使用します
これが私のアダプターの例です:
_public class Adapter extends BaseAdapter {
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater = null;
public ImageLoader imageLoader;
public MediaItemAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data = d;
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader = new ImageLoader(activity.getApplicationContext());
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
if (convertView == null) {
vi = inflater.inflate(R.layout.item_composer, null);
}
TextView title = (TextView) vi.findViewById(R.id.item_title); // title
TextView price = (TextView) vi.findViewById(R.id.price);
return vi;
}
}
_
アダプターの呼び出し:
_List myList = new ArrayList<HashMap<String, String>>();
Adapter ma = new Adapter(this, myList);
_
アダプタの初期化の前にmyListを空にすることができます。
次に、リストを使用して操作を行います。
_myList.add(someElement);
ma.notifyDataSetChanged();
_
すべてのアイテムを削除する必要がある場合:
_myList.clear();
ma.notifyDataSetChanged();
_
そのような実装は非常に無限であり、問題なく15000以上の要素を見ました。
私の場合、問題は、新しいデータが設定されるたびにListView.setAdapter(adapter)
を呼び出していたため、位置もリセットされ、ビューが先頭にジャンプすることでした。
冗長なsetAdapter(...)
呼び出しを削除すると修正されました。
このように別の方法でそれを行うことができます
int position = scrollView.getSelectedItemPosition();
notifyDataSetChanged();
scrollView.setSelection(position);
アダプタがArrayList
をサブクラス化している場合、adapter.clear()
を呼び出すとnotifyDataSetChanged()
が呼び出され、スクロール位置が失われます。これを防ぐには、最初にsetNotifyOnChange(false)
を呼び出すことを検討してください。
@Yarthの答えは、あなたが電話した場合、これを引き起こしたことがわかった1つの小さな問題を追加するのに役立ちました
listview.setVisibility(View.VISIBLE);
また、リスト全体が上部にスクロールされます。