Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a closed (circular) ListView?

My colleague Joe, and I believe we have found a simpler way to solve the same problem. In our solution though instead of extending BaseAdapter we extend ArrayAdapter.

The code is as follows :

public class CircularArrayAdapter< T > extends ArrayAdapter< T >
{   

        public static final int HALF_MAX_VALUE = Integer.MAX_VALUE/2;
        public final int MIDDLE;
        private T[] objects;

        public CircularArrayAdapter(Context context, int textViewResourceId, T[] objects)
        {
            super(context, textViewResourceId, objects);
            this.objects = objects;
            MIDDLE = HALF_MAX_VALUE - HALF_MAX_VALUE % objects.length;
        }

        @Override
        public int getCount()
        {
            return Integer.MAX_VALUE;
        }

        @Override
        public T getItem(int position) 
        {
            return objects[position % objects.length];
        }
 }

So this creates a class called CircularArrayAdapter which take an object type T (which may be anything) and uses it to create an array list. T is commonly a string though may be anything.

The constructor is the same as is for ArrayAdapter though initializes a constant called middle. This is the middle of the list. No matter what the length of the array MIDDLE can be used to center the ListView in the mid of the list.

getCount() is overrides to return a huge value as is done above creating a huge list.

getItem() is overrides to return the fake position on the array. Thus when filling the list the list is filled with objects in a looping manner.

At this point CircularArrayAdapter simply replaces ArrayAdapter in the file creating the ListView.

To centre the ListView the fallowing line must be inserted in your file creating the ListView after the ListView object has been initialised:

listViewObject.setSelectionFromTop(nameOfAdapterObject.MIDDLE, 0);

and using the MIDDLE constant previously initialized for the list the view is centered with the top item of the list at the top of the screen.

: ) ~ Cheers, I hope this solution is useful.


The solution you mention is the one I told other developers to use in the past. In getCount(), simply return Integer.MAX_VALUE, it will give you about 2 billion items, which should be enough.


I have, or I think I have done it right, based on the answers above. Hope this will help you.

private static class RecipeListAdapter extends BaseAdapter {
    private static LayoutInflater   mInflater;
    private Integer[]               mCouponImages;
    private static ImageView        viewHolder;
    public RecipeListAdapter(Context c, Integer[] coupomImages) {
        RecipeListAdapter.mInflater = LayoutInflater.from(c);
        this.mCouponImages = coupomImages;
    }
    @Override
    public int getCount() {
        return Integer.MAX_VALUE;
    }

    @Override
    public Object getItem(int position) {
       // you can do your own tricks here. to let it display the right item in your array.
        return position % mCouponImages.length;
    }

    @Override
    public long getItemId(int position) {
        return position;
        // return position % mCouponImages.length;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.coupon_list_item, null);
            viewHolder = (ImageView) convertView.findViewById(R.id.item_coupon);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ImageView) convertView.getTag();
        }

        viewHolder.setImageResource(this.mCouponImages[position %     mCouponImages.length]);
        return convertView;
    }

}

And you would like to do this if you want to scroll down the list. Commonly we can just scroll up and list then scroll down.

// see how many items we would like to sroll. in this case, Integer.MAX_VALUE

int listViewLength = adapter.getCount();

// see how many items a screen can dispaly, I use variable "span"
    final int span = recipeListView.getLastVisiblePosition() - recipeListView.getFirstVisiblePosition();

// see how many pages we have

int howManySpans = listViewLength / span;

// see where do you want to be when start the listview. you dont have to do the "-3" stuff. it is for my app to work right.

recipeListView.setSelection((span * (howManySpans / 2)) - 3);

I could see some good answers for this, One of my friend has tried to achieve this via a simple solution. Check the github project.