Android ListView ArrayAdapter обновления данных Лучшие практики - PullRequest
4 голосов
/ 26 августа 2010

У меня есть действие с несколькими представлениями списка, которые непрерывно получают новые значения из потока сокета, другой поток анализирует данные и обновляет адаптеры массива, затем поток пользовательского интерфейса вызывает notifyDataSetChanged (), чтобы вызвать обновление списка.

Моя проблема в том, что я обновляю весь список пару раз в секунду, это приводит к тому, что пользовательский интерфейс становится слишком медленным, когда требуется анимация.

Мне было интересно, как лучше обновлять несколько списков с несколькими изменениями значений каждую секунду?

Спасибо, Тотем.

Ответы [ 3 ]

16 голосов
/ 26 августа 2010

Я бы точно следовал рекомендациям, которые они дали в Google IO в этом году.

Видео просмотра Google IO

3 голосов
/ 26 августа 2010

Вы должны использовать курсоры (если требуется контент-провайдеры) и ListActivity.Пользовательский интерфейс автоматически обновляется, как только появляются изменения, и в случае нулевых наборов данных в списке автоматически отображается соответствующее представление.

Следующие примеры решают его с помощью поставщиков содержимого:

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: список и android: пустые теги.Это требуется для действия со списком.

В методе 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 голосов
/ 26 августа 2010

Да, это видео очень полезно. Один из самых важных моментов в том, что вам следует перезапустить метод 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 в видео.

...