package com.tiger.quicknews.wedget.viewimage.Animations; import android.content.Context; import android.content.res.TypedArray; import android.os.Message; import android.support.v4.view.PagerAdapter; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.animation.Interpolator; import android.widget.RelativeLayout; import com.tiger.quicknews.R; import com.tiger.quicknews.wedget.viewimage.Indicators.PagerIndicator; import com.tiger.quicknews.wedget.viewimage.SliderTypes.BaseSliderView; import com.tiger.quicknews.wedget.viewimage.Transformers.AccordionTransformer; import com.tiger.quicknews.wedget.viewimage.Transformers.BackgroundToForegroundTransformer; import com.tiger.quicknews.wedget.viewimage.Transformers.BaseTransformer; import com.tiger.quicknews.wedget.viewimage.Transformers.CubeInTransformer; import com.tiger.quicknews.wedget.viewimage.Transformers.DefaultTransformer; import com.tiger.quicknews.wedget.viewimage.Transformers.DepthPageTransformer; import com.tiger.quicknews.wedget.viewimage.Transformers.FadeTransformer; import com.tiger.quicknews.wedget.viewimage.Transformers.FlipHorizontalTransformer; import com.tiger.quicknews.wedget.viewimage.Transformers.FlipPageViewTransformer; import com.tiger.quicknews.wedget.viewimage.Transformers.ForegroundToBackgroundTransformer; import com.tiger.quicknews.wedget.viewimage.Transformers.RotateDownTransformer; import com.tiger.quicknews.wedget.viewimage.Transformers.RotateUpTransformer; import com.tiger.quicknews.wedget.viewimage.Transformers.StackTransformer; import com.tiger.quicknews.wedget.viewimage.Transformers.TabletTransformer; import com.tiger.quicknews.wedget.viewimage.Transformers.ZoomInTransformer; import com.tiger.quicknews.wedget.viewimage.Transformers.ZoomOutSlideTransformer; import com.tiger.quicknews.wedget.viewimage.Transformers.ZoomOutTransformer; import com.tiger.quicknews.wedget.viewimage.Tricks.FixedSpeedScroller; import com.tiger.quicknews.wedget.viewimage.Tricks.InfinitePagerAdapter; import com.tiger.quicknews.wedget.viewimage.Tricks.InfiniteViewPager; import com.tiger.quicknews.wedget.viewimage.Tricks.ViewPagerEx; import java.lang.reflect.Field; import java.util.Timer; import java.util.TimerTask; /** * SliderLayout is compound layout. This is combined with * {@link com.example.androidimageslider.wedget.viewimage.Indicators.daimajia.slider.library.Indicators.PagerIndicator} * and * {@link com.example.androidimageslider.wedget.viewimage.Tricks.daimajia.slider.library.Tricks.ViewPagerEx} * . There is some properties you can set in XML: indicator_visibility visible * invisible indicator_shape oval rect indicator_selected_color * indicator_unselected_color indicator_selected_drawable * indicator_unselected_drawable pager_animation Default Accordion * Background2Foreground CubeIn DepthPage Fade FlipHorizontal FlipPage * Foreground2Background RotateDown RotateUp Stack Tablet ZoomIn ZoomOutSlide * ZoomOut pager_animation_span */ public class SliderLayout extends RelativeLayout { private Context mContext; /** * InfiniteViewPager is extended from ViewPagerEx. As the name says, it can * scroll without bounder. */ private InfiniteViewPager mViewPager; /** * InfiniteViewPager adapter. */ private SliderAdapter mSliderAdapter; /** * {@link com.example.androidimageslider.wedget.viewimage.Tricks.daimajia.slider.library.Tricks.ViewPagerEx} * indicator. */ private PagerIndicator mIndicator; /** * A timer and a TimerTask using to cycle the * {@link com.example.androidimageslider.wedget.viewimage.Tricks.daimajia.slider.library.Tricks.ViewPagerEx} * . */ private Timer mCycleTimer; private TimerTask mCycleTask; /** * For resuming the cycle, after user touch or click the * {@link com.example.androidimageslider.wedget.viewimage.Tricks.daimajia.slider.library.Tricks.ViewPagerEx} * . */ private Timer mResumingTimer; private TimerTask mResumingTask; /** * If * {@link com.example.androidimageslider.wedget.viewimage.Tricks.daimajia.slider.library.Tricks.ViewPagerEx} * is Cycling */ private boolean mCycling; /** * If auto recover after user touch the * {@link com.example.androidimageslider.wedget.viewimage.Tricks.daimajia.slider.library.Tricks.ViewPagerEx} */ private boolean mAutoRecover; private int mTransformerId; /** * {@link com.example.androidimageslider.wedget.viewimage.Tricks.daimajia.slider.library.Tricks.ViewPagerEx} * transformer time span. */ private int mTransformerSpan; private boolean mAutoCycle; /** * Visibility of * {@link com.example.androidimageslider.wedget.viewimage.Indicators.daimajia.slider.library.Indicators.PagerIndicator} */ private PagerIndicator.IndicatorVisibility mIndicatorVisibility = PagerIndicator.IndicatorVisibility.Visible; /** * {@link com.example.androidimageslider.wedget.viewimage.Tricks.daimajia.slider.library.Tricks.ViewPagerEx} * 's transformer */ private BaseTransformer mViewPagerTransformer; /** * @see com.example.androidimageslider.wedget.viewimage.Animations.daimajia.slider.library.Animations.BaseAnimationInterface */ private BaseAnimationInterface mCustomAnimation; /** * {@link com.example.androidimageslider.wedget.viewimage.Indicators.daimajia.slider.library.Indicators.PagerIndicator} * shape, rect or oval. */ public SliderLayout(Context context) { this(context, null); } public SliderLayout(Context context, AttributeSet attrs) { this(context, attrs, R.attr.SliderStyle); } public SliderLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mContext = context; LayoutInflater.from(context).inflate(R.layout.slider_layout, this, true); final TypedArray attributes = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SliderLayout, defStyle, 0); mTransformerSpan = attributes.getInteger(R.styleable.SliderLayout_pager_animation_span, 1100); mTransformerId = attributes.getInt(R.styleable.SliderLayout_pager_animation, Transformer.Default.ordinal()); mAutoCycle = attributes.getBoolean(R.styleable.SliderLayout_auto_cycle, true); int visibility = attributes.getInt(R.styleable.SliderLayout_indicator_visibility, 0); for (PagerIndicator.IndicatorVisibility v : PagerIndicator.IndicatorVisibility.values()) { if (v.ordinal() == visibility) { mIndicatorVisibility = v; break; } } mSliderAdapter = new SliderAdapter(mContext); PagerAdapter wrappedAdapter = new InfinitePagerAdapter(mSliderAdapter); mViewPager = (InfiniteViewPager) findViewById(R.id.daimajia_slider_viewpager); mViewPager.setAdapter(wrappedAdapter); mViewPager.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_UP: recoverCycle(); break; } return false; } }); attributes.recycle(); setPresetIndicator(PresetIndicators.Center_Bottom); setPresetTransformer(mTransformerId); setSliderTransformDuration(mTransformerSpan, null); setIndicatorVisibility(mIndicatorVisibility); if (mAutoCycle) { startAutoCycle(); } } public void setCustomIndicator(PagerIndicator indicator) { if (mIndicator != null) { mIndicator.destroySelf(); } mIndicator = indicator; mIndicator.setIndicatorVisibility(mIndicatorVisibility); mIndicator.setViewPager(mViewPager); mIndicator.redraw(); } public <T extends BaseSliderView> void addSlider(T imageContent) { mSliderAdapter.addSlider(imageContent); } public void startAutoCycle() { startAutoCycle(1000, 3400, true); } /** * start auto cycle. * * @param delay delay time * @param period period time. * @param autoRecover */ public void startAutoCycle(long delay, long period, boolean autoRecover) { mCycleTimer = new Timer(); mAutoRecover = autoRecover; mCycleTask = new TimerTask() { @Override public void run() { mh.sendEmptyMessage(0); } }; mCycleTimer.schedule(mCycleTask, delay, period); mCycling = true; } /** * pause auto cycle. */ private void pauseAutoCycle() { if (mCycling) { mCycleTimer.cancel(); mCycleTask.cancel(); mCycling = false; } else { if (mResumingTimer != null && mResumingTask != null) { recoverCycle(); } } } /** * stop the auto circle */ public void stopAutoCycle() { if (mCycleTask != null) { mCycleTask.cancel(); } if (mCycleTimer != null) { mCycleTimer.cancel(); } if (mResumingTimer != null) { mResumingTimer.cancel(); } if (mResumingTask != null) { mResumingTask.cancel(); } } /** * when paused cycle, this method can weak it up. */ private void recoverCycle() { if (!mAutoRecover) { return; } if (!mCycling) { if (mResumingTask != null && mResumingTimer != null) { mResumingTimer.cancel(); mResumingTask.cancel(); } mResumingTimer = new Timer(); mResumingTask = new TimerTask() { @Override public void run() { startAutoCycle(); } }; mResumingTimer.schedule(mResumingTask, 6000); } } private final android.os.Handler mh = new android.os.Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); mViewPager.nextItem(); } }; @Override public boolean onInterceptTouchEvent(MotionEvent ev) { int action = ev.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: pauseAutoCycle(); break; } return false; } /** * set ViewPager transformer. * * @param reverseDrawingOrder * @param transformer */ public void setPagerTransformer(boolean reverseDrawingOrder, BaseTransformer transformer) { mViewPagerTransformer = transformer; mViewPagerTransformer.setCustomAnimationInterface(mCustomAnimation); mViewPager.setPageTransformer(reverseDrawingOrder, mViewPagerTransformer); } /** * set the duration between two slider changes. * * @param period * @param interpolator */ public void setSliderTransformDuration(int period, Interpolator interpolator) { try { Field mScroller = ViewPagerEx.class.getDeclaredField("mScroller"); mScroller.setAccessible(true); FixedSpeedScroller scroller = new FixedSpeedScroller(mViewPager.getContext(), interpolator, period); mScroller.set(mViewPager, scroller); } catch (Exception e) { } } /** * preset transformers and their names */ public enum Transformer { Default("Default"), Accordion("Accordion"), Background2Foreground("Background2Foreground"), CubeIn("CubeIn"), DepthPage("DepthPage"), Fade("Fade"), FlipHorizontal("FlipHorizontal"), FlipPage("FlipPage"), Foreground2Background("Foreground2Background"), RotateDown("RotateDown"), RotateUp("RotateUp"), Stack("Stack"), Tablet("Tablet"), ZoomIn("ZoomIn"), ZoomOutSlide("ZoomOutSlide"), ZoomOut("ZoomOut"); private final String name; private Transformer(String s) { name = s; } @Override public String toString() { return name; } public boolean equals(String other) { return (other == null) ? false : name.equals(other); } }; /** * set a preset viewpager transformer by id. * * @param transformerId */ public void setPresetTransformer(int transformerId) { for (Transformer t : Transformer.values()) { if (t.ordinal() == transformerId) { setPresetTransformer(t); break; } } } /** * set preset PagerTransformer via the name of transforemer. * * @param transformerName */ public void setPresetTransformer(String transformerName) { for (Transformer t : Transformer.values()) { if (t.equals(transformerName)) { setPresetTransformer(t); return; } } } /** * Inject your custom animation into PageTransformer, you can know more * details in * {@link com.example.androidimageslider.wedget.viewimage.Animations.daimajia.slider.library.Animations.BaseAnimationInterface} * , and you can see a example in * {@link com.example.androidimageslider.wedget.viewimage.Animations.daimajia.slider.library.Animations.DescriptionAnimation} * * @param animation */ public void setCustomAnimation(BaseAnimationInterface animation) { mCustomAnimation = animation; if (mViewPagerTransformer != null) { mViewPagerTransformer.setCustomAnimationInterface(mCustomAnimation); } } /** * pretty much right? enjoy it. :-D * * @param ts */ public void setPresetTransformer(Transformer ts) { // // special thanks to https://github.com/ToxicBakery/ViewPagerTransforms // BaseTransformer t = null; switch (ts) { case Default: t = new DefaultTransformer(); break; case Accordion: t = new AccordionTransformer(); break; case Background2Foreground: t = new BackgroundToForegroundTransformer(); break; case CubeIn: t = new CubeInTransformer(); break; case DepthPage: t = new DepthPageTransformer(); break; case Fade: t = new FadeTransformer(); break; case FlipHorizontal: t = new FlipHorizontalTransformer(); break; case FlipPage: t = new FlipPageViewTransformer(); break; case Foreground2Background: t = new ForegroundToBackgroundTransformer(); break; case RotateDown: t = new RotateDownTransformer(); break; case RotateUp: t = new RotateUpTransformer(); break; case Stack: t = new StackTransformer(); break; case Tablet: t = new TabletTransformer(); break; case ZoomIn: t = new ZoomInTransformer(); break; case ZoomOutSlide: t = new ZoomOutSlideTransformer(); break; case ZoomOut: t = new ZoomOutTransformer(); break; } setPagerTransformer(true, t); } /** * Set the visibility of the indicators. * * @param visibility */ public void setIndicatorVisibility(PagerIndicator.IndicatorVisibility visibility) { if (mIndicator == null) { return; } mIndicator.setIndicatorVisibility(visibility); } public PagerIndicator.IndicatorVisibility getIndicatorVisibility() { if (mIndicator == null) { return mIndicator.getIndicatorVisibility(); } return PagerIndicator.IndicatorVisibility.Invisible; } /** * get the * {@link com.example.androidimageslider.wedget.viewimage.Indicators.daimajia.slider.library.Indicators.PagerIndicator} * instance. You can manipulate the properties of the indicator. * * @return */ public PagerIndicator getPagerIndicator() { return mIndicator; } public enum PresetIndicators { Center_Bottom("Center_Bottom", R.id.default_center_bottom_indicator), Right_Bottom("Right_Bottom", R.id.default_bottom_right_indicator), Left_Bottom("Left_Bottom", R.id.default_bottom_left_indicator), Center_Top("Center_Top", R.id.default_center_top_indicator), Right_Top("Right_Top", R.id.default_center_top_right_indicator), Left_Top("Left_Top", R.id.default_center_top_left_indicator); private final String name; private final int id; private PresetIndicators(String name, int id) { this.name = name; this.id = id; } @Override public String toString() { return name; } public int getResourceId() { return id; } } public void setPresetIndicator(PresetIndicators presetIndicator) { PagerIndicator pagerIndicator = (PagerIndicator) findViewById(presetIndicator .getResourceId()); setCustomIndicator(pagerIndicator); } private InfinitePagerAdapter getWrapperAdapter() { PagerAdapter adapter = mViewPager.getAdapter(); if (adapter != null) { return (InfinitePagerAdapter) adapter; } else { return null; } } private SliderAdapter getRealAdapter() { PagerAdapter adapter = mViewPager.getAdapter(); if (adapter != null) { return ((InfinitePagerAdapter) adapter).getRealAdapter(); } return null; } /** * remove the slider at the position. Notice: It's a not perfect method, a * very small bug still exists. */ public void removeSliderAt(int position) { if (getRealAdapter() != null) { getRealAdapter().removeSliderAt(position); mViewPager.setCurrentItem(mViewPager.getCurrentItem(), false); } } /** * remove all the sliders. Notice: It's a not perfect method, a very small * bug still exists. */ public void removeAllSliders() { if (getRealAdapter() != null) { int count = getRealAdapter().getCount(); getRealAdapter().removeAllSliders(); // a small bug, but fixed by this trick. // bug: when remove adapter's all the sliders.some caching slider // still alive. mViewPager.setCurrentItem(mViewPager.getCurrentItem() + count, false); } } }