Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Large dataset with ArrayAdapter and ListView in Android

For learning purposes I would like to write an Android application that will display a list of numbers from 0 to Integer.MAX_VALUE. I currently have an app that will display numbers from 0 to 100, this is easy because you can just create an array of numbers and then pass that to the Adapter, currently using ArrayAdapter. If I try that with an extremely large array the program crashes when it uses all available memory.

Looking at more advanced applications I noticed people with large data sets using databases and CursorAdapters. If that is the correct thing to do I can start reading on that. What I would like to do (although feel free to tell me this is wrong) is seed my ArrayAdapter with an array of length 100, or some relatively small length. From there as the user scrolls up or down I would like to modify the values in the array (or the Adapter) to increase as the user scrolls down, removing the smallest items in the list and appending larger values to the end of the list. If the user scrolls up, I would like to remove items from the end of the list and add new smaller values to the beginning.

As I stated for this project I have very little done so far.

package example.VariableListView;

import java.util.ArrayList;

import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;

public class variablelistview extends ListActivity {    
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);

            ArrayList<Integer> intItems = new ArrayList<Integer>();
            for (int ii = 0; ii < 100; ii++) {
                    intItems.add(ii);
            }
        this.setListAdapter(new ArrayAdapter<Integer>(this,
                            android.R.layout.simple_list_item_1, intItems));
    }

}

thanks in advance for any and all help.

like image 276
user442585 Avatar asked Jun 13 '11 01:06

user442585


2 Answers

The type of Adapter you use should depend on the type of data you're trying to present. Adapters ideally are a very thin object that binds items from your data set to Views. ArrayAdapter provides this for small bounded data sets, CursorAdapter provides this for data sets resulting from a SQLite query.

Not all data sets will fit into the molds presented by the provided Adapter classes in the Android framework, but writing your own is easy. Presenting a list of all positive integers is a good example because it doesn't need to involve communicating with an underlying data model at all. While maintaining a sliding window into a large data set can be a useful approach for some data, it's not needed here.

Start from BaseAdapter:

public class IntRangeAdapter extends BaseAdapter {
    private LayoutInflater mInflater;
    private int mItemResource;

    public IntRangeAdapter(Context context, int itemLayout) {
        // We'll use this to generate new item layouts
        mInflater = LayoutInflater.from(context);

        // This is the layout resource we'll use for each item
        mItemResource = itemLayout;
    }

    public int getCount() {
        // Since this adapter presents all positive integers,
        // we have Integer.MAX_VALUE items.
        return Integer.MAX_VALUE;
    }

    public Object getItem(int position) {
        // Each item is simply its position index.
        return position;
    }

    public long getItemId(int position) {
        // Our items won't change and we don't need stable IDs,
        // so the position of an item is also its ID.
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            // Inflate a new item layout if we weren't given an existing
            // one to reuse via the convertView parameter.
            convertView = mInflater.inflate(mItemResource, parent, false);
        }

        // Find the TextView where we will label the item.
        // (This can be optimized a bit for more complex layouts
        // but we won't bother for this example.)
        TextView tv = (TextView) convertView.findViewById(android.R.id.text1);

        // Set the item text based on its position.
        tv.setText("Item " + position);

        return convertView;
    }
}

Using it from your posted Activity code would then be a matter of changing your setAdapter call and removing the loop to set up the data:

this.setListAdapter(new IntRangeAdapter(this,
        android.R.layout.simple_list_item_1));

If you'd like some more info about using ListViews, this talk from Google I/O 2010 gives a decent intro: http://www.youtube.com/watch?v=wDBM6wVEO70

like image 166
adamp Avatar answered Nov 18 '22 15:11

adamp


Probably the easiest solution is to implement your own Adapter (http://developer.android.com/reference/android/widget/Adapter.html) rather than trying to force a CursorAdapter or ArrayAdapter to do something it isn't designed for.

The methods should all be very easy to implement. For example:

int getCount() => Integer.MAX_VALUE
Object getItem(int position) => position
like image 43
Christopher Souvey Avatar answered Nov 18 '22 14:11

Christopher Souvey