Android ListView ArrayAdapter数据更新最佳实践

发布于 2024-09-16 10:01:12 字数 201 浏览 7 评论 0原文

我有一个具有多个列表视图的活动,这些视图不断从套接字线程接收新值,另一个线程解析数据并更新数组适配器,然后 ui 线程调用notifyDataSetChanged() 来刷新列表。

我的问题是,我每秒刷新所有列表几次,这会导致用户界面在需要发生某些动画时非常滞后。

我想知道每秒更新多个值更改的多个列表的最佳方法是什么?

谢谢, 图腾。

I have an activity with multiple list views that are continuously receiving new values form a socket thread, another thread parses the data and updates the array adapters, then the ui thread calls notifyDataSetChanged() to cause the list to refresh.

My issue is that im refreshing all the list a couple of time a second, this causes the UI to be very laggy when some animations need to happen.

I was wondering what the best way is to update multiple lists with multiple value changes every second?

Thanks,
Totem.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

清君侧 2024-09-23 10:01:12

我肯定会遵循他们今年在 Google IO 上给出的指导方针。

Google IO 列表视图视频

I would definately follow the guidelines they gave at Google IO this year.

Google IO listview Video

雅心素梦 2024-09-23 10:01:12

您应该使用 Cursors(如果需要内容提供程序)和 ListActivity。一旦发生更改,UI 就会自动更新,如果数据集为空,列表会自动显示相关视图。

以下示例使用内容提供程序解决该问题:

main.xml:

<ListView android:id="@id/android:list" android:layout_width="fill_parent"
        android:layout_height="wrap_content"></ListView>
    <TextView android:id="@id/android:empty" android:layout_width="fill_parent"
        android:gravity="center" android:layout_height="wrap_content"
        android:text="No data, please refresh!" />

注意 android:list 和 android:empty 标记。这些是列表活动所必需的。

在 onCreate() 方法中:

mCursor = getContentResolver().query(SOME_URI,
                null, null, null, null);

        ListView mListView = (ListView) findViewById(android.R.id.list);
        mListView.setAdapter(new CustomCusorAdapter(getApplicationContext(),
                mCursor));

如果您的视图很简单,您可以使用 SimpleCursorAdapter。由于视图复杂,我使用自己的适配器创建:

private class CustomCusorAdapter extends CursorAdapter {

        public CustomCusorAdapter(Context context, Cursor c) {
            super(context, c);
        }

        @Override
        public void bindView(View view, Context context, Cursor cursor) {


            Holder holder = (Holder) view.getTag();

            holder.tv.setText(cursor.getString(cursor
                    .getColumnIndex(COL1_NAME)));


        }

        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            View v = getLayoutInflater().inflate(
                    R.layout.layout_xml, null);

            Holder holder = new Holder();

            holder.tv = (TextView) v
                    .findViewById(R.id.tv);
            holder.cb= (CheckBox) v
                    .findViewById(R.id.cb);

            v.setTag(holder);
            return v;
        }

    }

    private class Holder {
        TextView tv;
        CheckBox cb;
    }

You should use Cursors (if required Content Providers) and ListActivity. The UI automatically updates as soon as there are changes and in case of null data sets, the list automatically displays a relevant view.

Following examples solves it using content providers:

main.xml:

<ListView android:id="@id/android:list" android:layout_width="fill_parent"
        android:layout_height="wrap_content"></ListView>
    <TextView android:id="@id/android:empty" android:layout_width="fill_parent"
        android:gravity="center" android:layout_height="wrap_content"
        android:text="No data, please refresh!" />

Notice the android:list and android:empty tags. These are required by the list activity.

In onCreate() method:

mCursor = getContentResolver().query(SOME_URI,
                null, null, null, null);

        ListView mListView = (ListView) findViewById(android.R.id.list);
        mListView.setAdapter(new CustomCusorAdapter(getApplicationContext(),
                mCursor));

You can use a SimpleCursorAdapter if your views are straight-forward. I created by own adapter because of the complex views:

private class CustomCusorAdapter extends CursorAdapter {

        public CustomCusorAdapter(Context context, Cursor c) {
            super(context, c);
        }

        @Override
        public void bindView(View view, Context context, Cursor cursor) {


            Holder holder = (Holder) view.getTag();

            holder.tv.setText(cursor.getString(cursor
                    .getColumnIndex(COL1_NAME)));


        }

        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            View v = getLayoutInflater().inflate(
                    R.layout.layout_xml, null);

            Holder holder = new Holder();

            holder.tv = (TextView) v
                    .findViewById(R.id.tv);
            holder.cb= (CheckBox) v
                    .findViewById(R.id.cb);

            v.setTag(holder);
            return v;
        }

    }

    private class Holder {
        TextView tv;
        CheckBox cb;
    }

是的,该视频非常有帮助。最大的收获之一是您应该回收传递到列表适配器 getView 方法中的 ConvertView:

    public View getView(int position, View convertView, ViewGroup parent){
        if (convertView == null) {
            convertView = mInflator.inflate(resource, parent, false);
        } 
        //do any view bindings for the row
        return convertView;
    }

另一个有用的一点是使用 ViewHolder 类进行视图回收。视频的时间约为 10:30。

Yes, that video is very helpful. One of the biggest take aways is that you should recycle the convertView passed into your list adapters getView method:

    public View getView(int position, View convertView, ViewGroup parent){
        if (convertView == null) {
            convertView = mInflator.inflate(resource, parent, false);
        } 
        //do any view bindings for the row
        return convertView;
    }

The other helpful bit was to use a ViewHolder class for the view recycling. It's at ~10:30 into the vid.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文