我想创建一个定制的ListView(或类似),它会像一个封闭的(圆形)之一:
- 向下滚动 - 中的最后一项是达到第一之后开始(..,N-1,N,1,2,...)
- 向上滚动 - 第一项后达到最后开始(..,2,1,N,N-1,..)
这听起来很简单的概念,但是,很显然,没有简单的方法来做到这一点。 任何人都可以点我正确的解决方案? 谢谢 !
我已经收到答复(从街道波士顿Android的开发者谷歌组),但它听起来莫名其妙丑陋:) -
我创建我自己的列表适配器(从BaseAdapter子类)这样做。
我编写我自己的列表适配器,因为其getCount将()方法返回一个HUUUUGE号这样的方式。
如果“X”被选择的项目,则该项目对应于适配器位置=“adapter.getCount()/ 2 + X”
而对于我的适配器的方法的getItem(INT位置),我看在我阵列备份适配器,并获取该项目的指标:(位置getCount将()/ 2)%myDataItems.length
你需要做一些“特殊”的东西,以正确使这一切工作,但你的想法。
原则上,它仍然有可能到达终点或列表的开始,但如果你设置getCount将(),以围绕一个亿左右,这是很难做到:-)
我的同事乔,我相信我们已经找到了解决同样的问题,简单的方法。 在我们的解决方案,而不是虽然扩大BaseAdapter我们扩展ArrayAdapter。
该代码是休耕:
public class CircularArrayAdapter extends ArrayAdapter
{
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];
}
}
因此,这会创建一个名为CircularArrayAdapter其采取的对象类型T(其可以是任何东西)类并用它来创建一个数组列表。 T是常见字符串,虽然可能是任何东西。
构造函数是是ArrayAdapter相同,虽然初始化一个常数称为中间。 这是列表的中间。 不管是什么阵列MIDDLE的长度可用于中心ListView控件列表的中旬。
getCount将被overrided如上面建立一个巨大的名单做返回一个巨大的价值。
的getItem被overrided返回阵列上的假位置。 从而填充列表当列表被填充以循环方式的对象。
此时CircularArrayAdapter只需将文件创建ListView控件中代替ArrayAdapter。
居中的ListView休耕行必须在文件创建ListView控件插入ListView的对象进行了初始化后:
listViewObject.setSelectionFromTop(nameOfAdapterObject.MIDDLE, 0);
并使用先前初始化用于视图居中与列表的屏幕的顶部的顶部项目的列表的MIDDLE恒定。
:)〜干杯,我希望这个解决方案是非常有用的。
你提到的解决方案是一个我跟其他开发商在过去的使用。 在getCount将(),简单地返回Integer.MAX_VALUE的,它会给你约2十亿的项目,这应该是足够的。
我有,或者我觉得我做了正确的基础上,上述问题的答案。 希望这会帮助你。
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;
}
}
你想,如果你想向下滚动列表来做到这一点。 通常我们只能向上滚动,然后列表向下滚动。
//看到我们想有多少项目来sroll。 在这种情况下,是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();
//看看我们多少个页面
int howManySpans = listViewLength / span;
//看到你想要当启动列表视图。 你没有做了“-3”的东西。 这是我的应用程序工作的权利。
recipeListView.setSelection((span * (howManySpans / 2)) - 3);
我可以看到一些这方面很好的答案,我的一个的朋友曾试图通过一个简单的解决方案来实现这一目标。 检查GitHub的项目。
如果使用LoadersCallbacks我创建了包装的典型光标这样MyCircularCursor类:
@Override
public void onLoadFinished(Loader<Cursor> pCursorLoader, Cursor pCursor) {
mItemListAdapter.swapCursor(new MyCircularCursor(pCursor));
}
装饰类代码是在这里:
public class MyCircularCursor implements Cursor {
private Cursor mCursor;
public MyCircularCursor(Cursor pCursor) {
mCursor = pCursor;
}
@Override
public int getCount() {
return mCursor.getCount() == 0 ? 0 : Integer.MAX_VALUE;
}
@Override
public int getPosition() {
return mCursor.getPosition();
}
@Override
public boolean move(int pOffset) {
return mCursor.move(pOffset);
}
@Override
public boolean moveToPosition(int pPosition) {
int position = MathUtils.mod(pPosition, mCursor.getCount());
return mCursor.moveToPosition(position);
}
@Override
public boolean moveToFirst() {
return mCursor.moveToFirst();
}
@Override
public boolean moveToLast() {
return mCursor.moveToLast();
}
@Override
public boolean moveToNext() {
if (mCursor.isLast()) {
mCursor.moveToFirst();
return true;
} else {
return mCursor.moveToNext();
}
}
@Override
public boolean moveToPrevious() {
if (mCursor.isFirst()) {
mCursor.moveToLast();
return true;
} else {
return mCursor.moveToPrevious();
}
}
@Override
public boolean isFirst() {
return false;
}
@Override
public boolean isLast() {
return false;
}
@Override
public boolean isBeforeFirst() {
return false;
}
@Override
public boolean isAfterLast() {
return false;
}
@Override
public int getColumnIndex(String pColumnName) {
return mCursor.getColumnIndex(pColumnName);
}
@Override
public int getColumnIndexOrThrow(String pColumnName) throws IllegalArgumentException {
return mCursor.getColumnIndexOrThrow(pColumnName);
}
@Override
public String getColumnName(int pColumnIndex) {
return mCursor.getColumnName(pColumnIndex);
}
@Override
public String[] getColumnNames() {
return mCursor.getColumnNames();
}
@Override
public int getColumnCount() {
return mCursor.getColumnCount();
}
@Override
public byte[] getBlob(int pColumnIndex) {
return mCursor.getBlob(pColumnIndex);
}
@Override
public String getString(int pColumnIndex) {
return mCursor.getString(pColumnIndex);
}
@Override
public short getShort(int pColumnIndex) {
return mCursor.getShort(pColumnIndex);
}
@Override
public int getInt(int pColumnIndex) {
return mCursor.getInt(pColumnIndex);
}
@Override
public long getLong(int pColumnIndex) {
return mCursor.getLong(pColumnIndex);
}
@Override
public float getFloat(int pColumnIndex) {
return mCursor.getFloat(pColumnIndex);
}
@Override
public double getDouble(int pColumnIndex) {
return mCursor.getDouble(pColumnIndex);
}
@Override
public int getType(int pColumnIndex) {
return 0;
}
@Override
public boolean isNull(int pColumnIndex) {
return mCursor.isNull(pColumnIndex);
}
@Override
public void deactivate() {
mCursor.deactivate();
}
@Override
@Deprecated
public boolean requery() {
return mCursor.requery();
}
@Override
public void close() {
mCursor.close();
}
@Override
public boolean isClosed() {
return mCursor.isClosed();
}
@Override
public void registerContentObserver(ContentObserver pObserver) {
mCursor.registerContentObserver(pObserver);
}
@Override
public void unregisterContentObserver(ContentObserver pObserver) {
mCursor.unregisterContentObserver(pObserver);
}
@Override
public void registerDataSetObserver(DataSetObserver pObserver) {
mCursor.registerDataSetObserver(pObserver);
}
@Override
public void unregisterDataSetObserver(DataSetObserver pObserver) {
mCursor.unregisterDataSetObserver(pObserver);
}
@Override
public void setNotificationUri(ContentResolver pCr, Uri pUri) {
mCursor.setNotificationUri(pCr, pUri);
}
@Override
public boolean getWantsAllOnMoveCalls() {
return mCursor.getWantsAllOnMoveCalls();
}
@Override
public Bundle getExtras() {
return mCursor.getExtras();
}
@Override
public Bundle respond(Bundle pExtras) {
return mCursor.respond(pExtras);
}
@Override
public void copyStringToBuffer(int pColumnIndex, CharArrayBuffer pBuffer) {
mCursor.copyStringToBuffer(pColumnIndex, pBuffer);
}
}