views:

71

answers:

3

Hi, 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.

+1  A: 

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

Google IO listview Video

Travis
A: 

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;
    }
Sameer Segal
A: 

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.

Poko