Android ListView ArrayAdapter数据更新最佳实践

时间:2010-08-26 13:44:50

标签: android listview adapter

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

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

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

谢谢,   图腾。

3 个答案:

答案 0 :(得分:16)

我肯定会遵循他们今年在Google IO上的指导原则。

Google IO listview Video

答案 1 :(得分:3)

您应该使用游标(如果需要内容提供程序)和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;
    }

答案 2 :(得分:2)

是的,该视频非常有用。最大的收获之一就是你应该将转换后的convertView传递给你的列表适配器getView方法:

    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。