Java tutorial
/* * * MIT License * * Copyright (c) 2017 Alibaba Group * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ package com.tmall.ultraviewpager; import android.database.DataSetObserver; import android.os.Parcelable; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.support.v7.widget.RecyclerView; import android.util.SparseArray; import android.view.View; import android.view.ViewGroup; import android.widget.RelativeLayout; import java.util.HashMap; import java.util.Map; /** * Created by mikeafc on 15/11/25. */ class UltraViewPagerAdapter extends PagerAdapter { interface UltraViewPagerCenterListener { void center(); void resetPosition(); } private static final int INFINITE_RATIO = 400; private PagerAdapter adapter; private boolean enableLoop; private float multiScrRatio = Float.NaN; private boolean hasCentered; //ensure that the first item is in the middle when enabling loop-mode private int scrWidth; private int infiniteRatio; private UltraViewPagerCenterListener centerListener; private SparseArray viewArray = new SparseArray(); public UltraViewPagerAdapter(PagerAdapter adapter) { this.adapter = adapter; infiniteRatio = INFINITE_RATIO; } @Override public int getCount() { int count; if (enableLoop) { if (adapter.getCount() == 0) { count = 0; } else { count = adapter.getCount() * infiniteRatio; } } else { count = adapter.getCount(); } return count; } @Override public Object instantiateItem(ViewGroup container, int position) { int realPosition = position; //TODO if (enableLoop && adapter.getCount() != 0) { realPosition = position % adapter.getCount(); } Object item = adapter.instantiateItem(container, realPosition); //TODO View childView = null; if (item instanceof View) childView = (View) item; if (item instanceof RecyclerView.ViewHolder) childView = ((RecyclerView.ViewHolder) item).itemView; ViewPager viewPager = (ViewPager) container; int childCount = viewPager.getChildCount(); for (int i = 0; i < childCount; i++) { View child = viewPager.getChildAt(i); if (isViewFromObject(child, item)) { viewArray.put(realPosition, child); break; } } if (isEnableMultiScr()) { if (scrWidth == 0) { scrWidth = container.getResources().getDisplayMetrics().widthPixels; } RelativeLayout relativeLayout = new RelativeLayout(container.getContext()); if (childView.getLayoutParams() != null) { RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams( (int) (scrWidth * multiScrRatio), ViewGroup.LayoutParams.MATCH_PARENT); layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE); childView.setLayoutParams(layoutParams); } container.removeView(childView); relativeLayout.addView(childView); container.addView(relativeLayout); return relativeLayout; } return item; } @Override public void destroyItem(ViewGroup container, int position, Object object) { int realPosition = position; //TODO if (enableLoop && adapter.getCount() != 0) realPosition = position % adapter.getCount(); if (isEnableMultiScr() && object instanceof RelativeLayout) { View child = ((RelativeLayout) object).getChildAt(0); ((RelativeLayout) object).removeAllViews(); adapter.destroyItem(container, realPosition, child); } else { adapter.destroyItem(container, realPosition, object); } viewArray.remove(realPosition); } public View getViewAtPosition(int position) { return (View) viewArray.get(position); } @Override public void finishUpdate(ViewGroup container) { // only need to set the center position when the loop is enabled if (!hasCentered) { if (adapter.getCount() > 0 && getCount() > adapter.getCount()) { centerListener.center(); } } hasCentered = true; adapter.finishUpdate(container); } @Override public boolean isViewFromObject(View view, Object object) { return adapter.isViewFromObject(view, object); } @Override public void restoreState(Parcelable bundle, ClassLoader classLoader) { adapter.restoreState(bundle, classLoader); } @Override public Parcelable saveState() { return adapter.saveState(); } @Override public void startUpdate(ViewGroup container) { adapter.startUpdate(container); } @Override public CharSequence getPageTitle(int position) { int virtualPosition = position % adapter.getCount(); return adapter.getPageTitle(virtualPosition); } @Override public float getPageWidth(int position) { return adapter.getPageWidth(position); } @Override public void setPrimaryItem(ViewGroup container, int position, Object object) { adapter.setPrimaryItem(container, position, object); } @Override public void unregisterDataSetObserver(DataSetObserver observer) { adapter.unregisterDataSetObserver(observer); } @Override public void registerDataSetObserver(DataSetObserver observer) { adapter.registerDataSetObserver(observer); } @Override public void notifyDataSetChanged() { super.notifyDataSetChanged(); adapter.notifyDataSetChanged(); } @Override public int getItemPosition(Object object) { return adapter.getItemPosition(object); } public PagerAdapter getAdapter() { return adapter; } public int getRealCount() { return adapter.getCount(); } void setEnableLoop(boolean status) { this.enableLoop = status; notifyDataSetChanged(); if (!status) { centerListener.resetPosition(); } else { try { centerListener.center(); } catch (Exception e) { } } } boolean isEnableLoop() { return enableLoop; } void setMultiScrRatio(float ratio) { multiScrRatio = ratio; } boolean isEnableMultiScr() { return !Float.isNaN(multiScrRatio) && multiScrRatio < 1f; } void setCenterListener(UltraViewPagerCenterListener listener) { centerListener = listener; } void setInfiniteRatio(int infiniteRatio) { this.infiniteRatio = infiniteRatio; } }