【问题标题】:How to maintain scroll position of listview when the adapter update适配器更新时如何保持listview的滚动位置
【发布时间】:2015-07-23 17:22:49
【问题描述】:

我将适配器与 listview 绑定,起初我获取了 10 条记录,然后当我滚动结束时,再次添加到 listview 中的项目,它工作得很好。

但是当我在滚动结束后添加项目时,那时项目已成功添加,然后列表视图位置设置为顶部。我想将该位置设置为新添加的项目。

这是我的代码:

滚动功能:

public void onScroll(AbsListView view, int firstVisibleItem,
                    int visibleItemCount, int totalItemCount) {               
    new items().execute();
}

异步函数:

class items extends AsyncTask<String, String, String> {

    @Override
    protected void onPreExecute() {
        ...
    }

    protected String doInBackground(String... args) {


        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("id", String.valueOf(id)));

        JSONObject json = jParser.makeHttpRequest(url, "GET",
                params);


        try {


            for (int i = 0; i < products.length(); i++) {

                JSONObject c = products.getJSONObject(i);

                // Storing each json item in variable
                String id = c.getString(TAG_PID);
                String name = c.getString(TAG_NAME);

                Product item = new Product(name, imageurl);
                product_name.add(item);

            }

        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
    return null;
}

protected void onPostExecute(String file_url) {
    // dismiss the dialog after getting all products
    pDialog.dismiss();


    adapter = new CategoryAdapter(context, product_name);

    category_linear.setAdapter(adapter);

}

基础适配器:

public class CategoryAdapter extends BaseAdapter {

    Context context;

    // protected List<String> m_List;
    protected List<Product> rowItems;

    public CategoryAdapter(Context context, List<Product> items) {
        this.context = context;
        this.rowItems = items;
    }

    public void addItemAll(List<Product> item) {
        //
        rowItems.addAll(item);
        notifyDataSetChanged();
    }


    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return rowItems.size();
    }

    @Override
    public Object getItem(int position) {
        return rowItems.get(position);
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public View getView(final int position, View convertView,
                        ViewGroup parent) {

        // TODO Auto-generated method stub

        if (convertView == null) {
            convertView = LayoutInflater.from(getActivity()).inflate(
                    R.layout.row, null);

        }

        Product rowItem = (Product) getItem(position);

        TextView text = ViewHolderPattern.get(convertView, R.id.item_name);

        text.setText(rowItem.getTitle());

        return convertView;
    }
}

现在如何在添加新项目时设置滚动位置。

当前,当添加新项目时,它将转到列表视图的顶部。

但我想将位置设置为新项目开始。

我该怎么做?

【问题讨论】:

  • 在 onScroll 回调中使用 getFirstVisiblePosition() 获取列表顶部可见项目的位置。并使用 setSelection() 方法在 onPostExecute() 回调中再次设置。

标签: android listview android-adapter android-scrollview android-scroll


【解决方案1】:

每次执行 AsyncTask 中的代码时,您都会创建一个新的适配器实例。即在您的 onPostExecute 函数中。而不是做

adapter = new CategoryAdapter(context, product_name);
category_linear.setAdapter(adapter);

你应该这样做

adapter.addItemAll(product_name);
adapter.notifyDataSetChanged();

还写如下

adapter = new CategoryAdapter(context, new List<Product>());
category_linear.setAdapter(adapter);

在您实例化您的 ListView 以使其工作之后。

您的列表中的数据将更新,您的位置将保持不变。

干杯!

【讨论】:

  • logcat 中的错误是什么?您也可以在从适配器的 addItemAll 函数中删除 notifyDataSetChanged() 后尝试。
  • logcat : fragment.CategoryFragment$items.onPostExecute(CategoryFragment.java:248) fragment.CategoryFragment$items.onPostExecute(CategoryFragment.java:1) at android.os.AsyncTask.finish(AsyncTask.java:632) at android.os.AsyncTask.access$600(AsyncTask.java:177) at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645) at android.os.Handler.dispatchMessage(Handler.java:110) at android.os.Looper.loop(Looper.java:193)
  • 更新了答案,请看看是否解决了目的。这也是logcat的整个错误吗?还是您从顶部错过了什么?
  • 应该在某个地方列出了一些异常,比如 NullPointerException 什么的?
  • 这意味着您的适配器即将为空。如果您在 onViewCreated 中实例化此片段中的适配器并将该适配器分配给列表视图,则应该解决。
猜你喜欢
  • 2012-03-04
  • 1970-01-01
  • 2013-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多