/* * Created by LuaView. * Copyright (c) 2017, Alibaba Group. All rights reserved. * * This source code is licensed under the MIT. * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree. */ package com.taobao.luaview.view.adapter; import android.util.SparseArray; import android.view.ViewGroup; import com.taobao.luaview.userdata.ui.UDViewPager; import com.taobao.luaview.view.indicator.circle.CycleIconPagerAdapter; import org.luaj.vm2.Globals; /** * Pager Adapter for loop * * @author song * @date 15/9/17 */ public class LVLoopPagerAdapter extends LVPagerAdapter implements CycleIconPagerAdapter { private boolean mIsLooping = false; private boolean mBoundaryCaching = false; private SparseArray<ToDestroy> mToDestroy = new SparseArray<ToDestroy>(); public LVLoopPagerAdapter(Globals globals, UDViewPager udListView) { super(globals, udListView); } @Override public void notifyDataSetChanged() { mToDestroy = new SparseArray<ToDestroy>(); super.notifyDataSetChanged(); } /** * real:[0,1,2,3] 真实的数据 * fake:[0,1,2,3,4,5] 虚拟的数据 * fake<->real: * 0->3 * 1->0 * 2->1 * 3->2 * 4->3 * 5->0 * * @param position * @return */ public int toRealPosition(int position) { if (mIsLooping) { int realCount = getRealCount(); if (realCount <= 0) { return 0; } else if (realCount <= 1) { return position; } int realPosition = (position - 1) % realCount; if (realPosition < 0) { realPosition += realCount; } return realPosition; } else { return position; } } /** * real:[0,1,2,3] 真实的数据 * fake:[0,1,2,3,4,5] 虚拟的数据 * real<->fake: * 3->4 * 0->1 * 1->2 * 2->3 * 3->4 * 0->1 * * @param position * @return */ public int toFakePosition(int position) { if (mIsLooping) { if (getRealCount() > 1) { return position + 1; } else { return 0; } } else { return position; } } @Override public int getCount() { if (mIsLooping) { return super.getCount() <= 1 ? super.getCount() : super.getCount() + 2; } else { return super.getCount(); } } public boolean shouldLooping() { return mIsLooping && getRealCount() > 1; } public int getRealCount() { return super.getCount(); } public int getRealFirstPosition() { if (mIsLooping) { return getRealCount() > 1 ? 1 : 0; } else { return 0; } } public int getRealLastPosition() { if (mIsLooping) { return getRealFirstPosition() + getRealCount() - 1; } else { return getRealCount() - 1; } } @Override public Object instantiateItem(ViewGroup container, int position) { if (mIsLooping) { final int realPosition = toRealPosition(position); if (mBoundaryCaching) { ToDestroy toDestroy = mToDestroy.get(position); if (toDestroy != null) { mToDestroy.remove(position); return toDestroy.object; } } return super.instantiateItem(container, realPosition); /*if (shouldLooping() && (position == 0 || position == getCount() - 1)) { return super.newItem(container, position); } else { final int realPosition = toRealPosition(position); return super.instantiateItem(container, realPosition); }*/ } else { return super.instantiateItem(container, position); } } @Override public void destroyItem(ViewGroup container, int position, Object object) { if (mIsLooping) { final int realPosition = toRealPosition(position); if (mBoundaryCaching && (realPosition == 0 || realPosition == getRealCount() - 1)) {//第一个或者最后一个 mToDestroy.put(position, new ToDestroy(container, realPosition, object)); } else { super.destroyItem(container, realPosition, object); } /*if (shouldLooping() && (position == 0 || position == getCount() - 1)) { super.destroyItem(container, position, object); } else { final int realPosition = toRealPosition(position); super.destroyItem(container, realPosition, object); }*/ } else { super.destroyItem(container, position, object); } } public void setLooping(boolean mIsLooping) { this.mIsLooping = mIsLooping; } public boolean isLooping() { return mIsLooping; } /** * Container class for caching the boundary views */ static class ToDestroy { ViewGroup container; int realPosition; Object object; public ToDestroy(ViewGroup container, int position, Object object) { this.container = container; this.realPosition = position; this.object = object; } } /** * bugfix: mIsLooping条件为真的时候,实际要绘制的indicator个数应该扣除掉两个虚拟的 * see: {@link com.taobao.luaview.view.viewpager.LoopViewPager} */ @Override public int getActualCount() { // if (mIsLooping) // return getCount()-2; // else return getCount(); } @Override public int getInstanceCount() { if (mIsLooping) return getCount()-2; else return getCount(); } }