如何创建一个封闭(循环)ListView?

use*_*076 57 customization android listview circular-buffer

我想创建一个自定义ListView(或类似),其行为类似于封闭(循环)的:

  1. 向下滚动 - 在到达最后一个项目后第一个开始(..,n-1,n,1,2,...)
  2. 向上滚动 - 在第一个项目到达后,最后一个开始(...,2,1,1,n,n-1,..)

这在概念上听起来很简单,但显然,没有直接的方法来做到这一点.谁能指出我正确的解决方案?谢谢 !

我已经收到一个答案(来自Streets Of Boston的Android开发者谷歌团体),但听起来有些丑陋:) -

我这样做是通过创建自己的列表适配器(从BaseAdapter子类).

我编写了自己的列表适配器,其getCount()方法返回一个HUUUUGE编号.

如果选择项'x',则此项对应于适配器位置='adapter.getCount()/ 2 + x'

对于我的适配器的方法getItem(int position),我查看我的数组备份适配器并获取索引上的项目:(position-getCount()/ 2)%myDataItems.length

你需要做一些更"特殊"的东西才能使它完全正常工作,但你明白了.

原则上,它仍然可以到达列表的结尾或开头,但如果你将getCount()设置为大约一百万左右,这很难做到:-)

Daw*_*son 84

我的同事乔,我相信我们找到了一种更简单的方法来解决同样的问题.在我们的解决方案中,我们扩展了ArrayAdapter而不是扩展BaseAdapter.

代码是休闲:

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];
        }
 }
Run Code Online (Sandbox Code Playgroud)

因此,这将创建一个名为CircularArrayAdapter的类,它接受一个对象类型T(可能是任何东西)并使用它来创建一个数组列表.T通常是一个字符串,但可能是任何东西.

尽管初始化了一个名为middle的常量,但构造函数与ArrayAdapter的构造函数相同.这是列表的中间部分.无论MIDDLE数组的长度如何都可以用于将ListView置于列表中间.

getCount被覆盖以返回一个巨大的值,就像创建一个巨大的列表一样.

覆盖getItem以返回数组上的伪位置.因此,当填充列表时,列表以循环方式填充对象.

此时,CircularArrayAdapter只是在创建ListView的文件中替换ArrayAdapter.

要使ListView居中,必须在初始化ListView对象后创建ListView的文件中插入以下行:

getCount()

并使用先前为列表初始化的MIDDLE常量,视图以屏幕顶部列表的顶部项目为中心.

:)〜干杯,我希望这个解决方案很有用.


Rom*_*Guy 13

你提到的解决方案是我告诉其他开发人员过去使用的解决方案.在getCount()中,只需返回Integer.MAX_VALUE,它将为您提供大约20亿个项目,这应该足够了.

  • @PaulLammertsma从底部进行布局也不会影响性能. (3认同)

Har*_*rry 8

基于上面的答案,我有,或者我认为我做得对.希望这会帮助你.

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;
    }

}
Run Code Online (Sandbox Code Playgroud)

如果你想向下滚动列表,你想这样做.通常我们可以向上滚动并列出然后向下滚动.

//查看我们想要滚动的项目数量.在这种情况下,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();
Run Code Online (Sandbox Code Playgroud)

//查看我们有多少页面

int howManySpans = listViewLength / span;
Run Code Online (Sandbox Code Playgroud)

//在启动列表视图时查看您想要的位置.你不必做"-3"的事情.这是我的应用程序正常工作.

recipeListView.setSelection((span * (howManySpans / 2)) - 3);
Run Code Online (Sandbox Code Playgroud)