notifyDataSetChanged()使列表刷新并滚动回到顶部

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了notifyDataSetChanged()使列表刷新并滚动回到顶部相关的知识,希望对你有一定的参考价值。

我正在尝试实现无限滚动列表视图但是当我调用notifyDataSetChanged()时,整个列表刷新然后滚动位置返回到顶部。

这是正常行为吗?如何才能简单地添加添加的项目而不刷新并保持滚动位置?

答案

这种行为不正常。没有看到你的代码我可以建议如下:

1)您没有从UI线程调用notifyDataSetChanged()。正确的方法:

runOnUiThread(new Runnable() {
    public void run() {
        adapter.notifyDataSetChanged();
    }
});

2)你不小心或不打电话给adapter.notifyDataSetInvalidated();

3)在您的适配器中,您覆盖adapter.notifyDataSetChanged();方法并添加指令以转到顶部

4)如果您使用列表填充适配器 - 每次都提供新列表,因此适配器设置会刷新。您应始终提供相同的列表。但是,您可以根据需要更改它。如果您要重置列表,请使用list.clear而不是list = new ArrayList();

这是我的适配器的一个例子:

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)以防止这种情况。

更多信息:https://stackoverflow.com/a/14719538/383761

另一答案

@Yarth的回答帮助我只是添加一个我刚刚发现的小问题,如果你打电话的话

listview.setVisibility(View.VISIBLE);

还会导致整个列表滚动到顶部。

以上是关于notifyDataSetChanged()使列表刷新并滚动回到顶部的主要内容,如果未能解决你的问题,请参考以下文章

调用 notifyDataSetChanged 时未更新带有 customAdapter 的 ListView?

片段中的 notifyDataSetChanged() 不刷新列表视图

在没有 notifyDataSetChanged 的​​情况下刷新列表?

我的适配器上的 notifyDataSetChanged() 没有更新列表视图,为啥?

notifyDataSetChanged() 在 BaseAdapter 中无法使用 android 中的复选框列表

列表视图未使用 notifydatasetchanged() 调用进行更新