Created
September 14, 2018 23:14
-
-
Save ebnrdwan/1c25b478363830a77946fb1a08cdee3f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ebnrdwan.io.parentalApp.Utilities.CustomWidgets; | |
import android.content.Context; | |
import android.content.res.TypedArray; | |
import android.os.Message; | |
import android.support.v4.view.PagerAdapter; | |
import android.support.v7.app.AppCompatActivity; | |
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.daimajia.slider.library.Animations.BaseAnimationInterface; | |
import com.daimajia.slider.library.Indicators.PagerIndicator; | |
import com.daimajia.slider.library.SliderAdapter; | |
import com.daimajia.slider.library.SliderTypes.BaseSliderView; | |
import com.daimajia.slider.library.Transformers.AccordionTransformer; | |
import com.daimajia.slider.library.Transformers.BackgroundToForegroundTransformer; | |
import com.daimajia.slider.library.Transformers.BaseTransformer; | |
import com.daimajia.slider.library.Transformers.CubeInTransformer; | |
import com.daimajia.slider.library.Transformers.DefaultTransformer; | |
import com.daimajia.slider.library.Transformers.DepthPageTransformer; | |
import com.daimajia.slider.library.Transformers.FadeTransformer; | |
import com.daimajia.slider.library.Transformers.FlipHorizontalTransformer; | |
import com.daimajia.slider.library.Transformers.FlipPageViewTransformer; | |
import com.daimajia.slider.library.Transformers.ForegroundToBackgroundTransformer; | |
import com.daimajia.slider.library.Transformers.RotateDownTransformer; | |
import com.daimajia.slider.library.Transformers.RotateUpTransformer; | |
import com.daimajia.slider.library.Transformers.StackTransformer; | |
import com.daimajia.slider.library.Transformers.TabletTransformer; | |
import com.daimajia.slider.library.Transformers.ZoomInTransformer; | |
import com.daimajia.slider.library.Transformers.ZoomOutSlideTransformer; | |
import com.daimajia.slider.library.Transformers.ZoomOutTransformer; | |
import com.daimajia.slider.library.Tricks.FixedSpeedScroller; | |
import com.daimajia.slider.library.Tricks.InfinitePagerAdapter; | |
import com.daimajia.slider.library.Tricks.InfiniteViewPager; | |
import com.daimajia.slider.library.Tricks.ViewPagerEx; | |
import java.lang.reflect.Field; | |
import java.util.Timer; | |
import java.util.TimerTask; | |
/** | |
* SliderLayout is compound layout. This is combined with {@link PagerIndicator} | |
* and {@link 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 ViewPagerEx} indicator. | |
*/ | |
private PagerIndicator mIndicator; | |
/** | |
* A timer and a TimerTask using to cycle the {@link ViewPagerEx}. | |
*/ | |
private Timer mCycleTimer; | |
private TimerTask mCycleTask; | |
/** | |
* For resuming the cycle, after user touch or click the {@link ViewPagerEx}. | |
*/ | |
private Timer mResumingTimer; | |
private TimerTask mResumingTask; | |
/** | |
* If {@link ViewPagerEx} is Cycling | |
*/ | |
private boolean mCycling; | |
/** | |
* Determine if auto recover after user touch the {@link ViewPagerEx} | |
*/ | |
private boolean mAutoRecover = true; | |
private int mTransformerId; | |
/** | |
* {@link ViewPagerEx} transformer time span. | |
*/ | |
private int mTransformerSpan = 1200; | |
private boolean mAutoCycle; | |
/** | |
* the duration between animation. | |
*/ | |
private long mSliderDuration = 4000; | |
/** | |
* Visibility of {@link PagerIndicator} | |
*/ | |
private PagerIndicator.IndicatorVisibility mIndicatorVisibility = PagerIndicator.IndicatorVisibility.Invisible; | |
/** | |
* {@link ViewPagerEx} 's transformer | |
*/ | |
private BaseTransformer mViewPagerTransformer; | |
/** | |
* @see BaseAnimationInterface | |
*/ | |
private BaseAnimationInterface mCustomAnimation; | |
/** | |
* {@link PagerIndicator} shape, rect or oval. | |
*/ | |
public SliderLayout(Context context) { | |
this(context,null); | |
} | |
public SliderLayout(Context context, AttributeSet attrs) { | |
this(context,attrs, com.daimajia.slider.library.R.attr.SliderStyle); | |
} | |
public SliderLayout(Context context, AttributeSet attrs, int defStyle) { | |
super(context, attrs, defStyle); | |
mContext = context; | |
LayoutInflater.from(context).inflate(com.daimajia.slider.library.R.layout.slider_layout, this, true); | |
final TypedArray attributes = context.getTheme().obtainStyledAttributes(attrs, com.daimajia.slider.library.R.styleable.SliderLayout, | |
defStyle,0); | |
mTransformerSpan = attributes.getInteger(com.daimajia.slider.library.R.styleable.SliderLayout_pager_animation_span, 1100); | |
mTransformerId = attributes.getInt(com.daimajia.slider.library.R.styleable.SliderLayout_pager_animation, Transformer.Default.ordinal()); | |
mAutoCycle = attributes.getBoolean(com.daimajia.slider.library.R.styleable.SliderLayout_auto_cycle,true); | |
int visibility = attributes.getInt(com.daimajia.slider.library.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(com.daimajia.slider.library.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 addOnPageChangeListener(ViewPagerEx.OnPageChangeListener onPageChangeListener){ | |
if(onPageChangeListener != null){ | |
mViewPager.addOnPageChangeListener(onPageChangeListener); | |
} | |
} | |
public void removeOnPageChangeListener(ViewPagerEx.OnPageChangeListener onPageChangeListener) { | |
mViewPager.removeOnPageChangeListener(onPageChangeListener); | |
} | |
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); | |
} | |
private android.os.Handler mh = new android.os.Handler(){ | |
@Override | |
public void handleMessage(Message msg) { | |
super.handleMessage(msg); | |
moveNextPosition(true); | |
} | |
}; | |
public void startAutoCycle(){ | |
startAutoCycle(mSliderDuration, mSliderDuration, mAutoRecover); | |
} | |
/** | |
* start auto cycle. | |
* @param delay delay time | |
* @param duration animation duration time. | |
* @param autoRecover if recover after user touches the slider. | |
*/ | |
public void startAutoCycle(long delay,long duration,boolean autoRecover){ | |
if(mCycleTimer != null) mCycleTimer.cancel(); | |
if(mCycleTask != null) mCycleTask.cancel(); | |
if(mResumingTask != null) mResumingTask.cancel(); | |
if(mResumingTimer != null) mResumingTimer.cancel(); | |
mSliderDuration = duration; | |
mCycleTimer = new Timer(); | |
mAutoRecover = autoRecover; | |
mCycleTask = new TimerTask() { | |
@Override | |
public void run() { | |
mh.sendEmptyMessage(0); | |
} | |
}; | |
mCycleTimer.schedule(mCycleTask,delay,mSliderDuration); | |
mCycling = true; | |
mAutoCycle = true; | |
} | |
/** | |
* pause auto cycle. | |
*/ | |
private void pauseAutoCycle(){ | |
if(mCycling){ | |
mCycleTimer.cancel(); | |
mCycleTask.cancel(); | |
mCycling = false; | |
}else{ | |
if(mResumingTimer != null && mResumingTask != null){ | |
recoverCycle(); | |
} | |
} | |
} | |
/** | |
* set the duration between two slider changes. the duration value must >= 500 | |
* @param duration | |
*/ | |
public void setDuration(long duration){ | |
if(duration >= 500){ | |
mSliderDuration = duration; | |
if(mAutoCycle && mCycling){ | |
startAutoCycle(); | |
} | |
} | |
} | |
/** | |
* stop the auto circle_unselected | |
*/ | |
public void stopAutoCycle(){ | |
if(mCycleTask!=null){ | |
mCycleTask.cancel(); | |
} | |
if(mCycleTimer!= null){ | |
mCycleTimer.cancel(); | |
} | |
if(mResumingTimer!= null){ | |
mResumingTimer.cancel(); | |
} | |
if(mResumingTask!=null){ | |
mResumingTask.cancel(); | |
} | |
mAutoCycle = false; | |
mCycling = false; | |
} | |
/** | |
* when paused cycle, this method can weak it up. | |
*/ | |
private void recoverCycle(){ | |
if(!mAutoRecover || !mAutoCycle){ | |
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); | |
} | |
} | |
@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){ | |
} | |
} | |
public void addOnPageChangeListener(AppCompatActivity mainActivity) { | |
} | |
/** | |
* 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; | |
} | |
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 BaseAnimationInterface}, | |
* and you can see a example in {@link com.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 PagerIndicator} instance. | |
* You can manipulate the properties of the indicator. | |
* @return | |
*/ | |
public PagerIndicator getPagerIndicator(){ | |
return mIndicator; | |
} | |
public enum PresetIndicators{ | |
Center_Bottom("Center_Bottom", com.daimajia.slider.library.R.id.default_center_bottom_indicator), | |
Right_Bottom("Right_Bottom", com.daimajia.slider.library.R.id.default_bottom_right_indicator), | |
Left_Bottom("Left_Bottom", com.daimajia.slider.library.R.id.default_bottom_left_indicator), | |
Center_Top("Center_Top", com.daimajia.slider.library.R.id.default_center_top_indicator), | |
Right_Top("Right_Top", com.daimajia.slider.library.R.id.default_center_top_right_indicator), | |
Left_Top("Left_Top", com.daimajia.slider.library.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; | |
} | |
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; | |
} | |
/** | |
* get the current item selectedPosition | |
* @return | |
*/ | |
public int getCurrentPosition(){ | |
if(getRealAdapter() == null) | |
throw new IllegalStateException("You did not set a slider adapter"); | |
return mViewPager.getCurrentItem() % getRealAdapter().getCount(); | |
} | |
/** | |
* get current slider. | |
* @return | |
*/ | |
public BaseSliderView getCurrentSlider(){ | |
if(getRealAdapter() == null) | |
throw new IllegalStateException("You did not set a slider adapter"); | |
int count = getRealAdapter().getCount(); | |
int realCount = mViewPager.getCurrentItem() % count; | |
return getRealAdapter().getSliderView(realCount); | |
} | |
/** | |
* remove the slider at the selectedPosition. 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); | |
} | |
} | |
/** | |
*set current slider | |
* @param position | |
*/ | |
public void setCurrentPosition(int position, boolean smooth) { | |
if (getRealAdapter() == null) | |
throw new IllegalStateException("You did not set a slider adapter"); | |
if(position >= getRealAdapter().getCount()){ | |
throw new IllegalStateException("Item selectedPosition is not exist"); | |
} | |
int p = mViewPager.getCurrentItem() % getRealAdapter().getCount(); | |
int n = (position - p) + mViewPager.getCurrentItem(); | |
mViewPager.setCurrentItem(n, smooth); | |
} | |
public void setCurrentPosition(int position) { | |
setCurrentPosition(position, true); | |
} | |
/** | |
* move to prev slide. | |
*/ | |
public void movePrevPosition(boolean smooth) { | |
if (getRealAdapter() == null) | |
throw new IllegalStateException("You did not set a slider adapter"); | |
mViewPager.setCurrentItem(mViewPager.getCurrentItem() - 1, smooth); | |
} | |
public void movePrevPosition(){ | |
movePrevPosition(true); | |
} | |
/** | |
* move to next slide. | |
*/ | |
public void moveNextPosition(boolean smooth) { | |
if (getRealAdapter() == null) | |
throw new IllegalStateException("You did not set a slider adapter"); | |
mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1, smooth); | |
} | |
public void moveNextPosition() { | |
moveNextPosition(true); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment