package com.mfh.comna.view.viewpager;
import java.lang.reflect.Field;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Interpolator;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.mfh.comna.R;
/**
* -----------------------------------------------------------------
*
* Copyright (C) 2014 ChunChen
*
* AutoSlideViewPager
*
* @version: v1.0.0
*
* @author: Caij
*
* Create Date: 2014.08.22
*
* -----------------------------------------------------------------
*/
public class AutoSlideViewPager extends RelativeLayout implements OnPageChangeListener {
private static final int WHAT = 1;
private static final int INTERVAL_TIME = 2000;
private static final double SCROOL_FACTOR = 1.0;
private Context context;
private ViewPager mViewPager;
/** Describe the title of the current page */
private TextView mDescriptionTextView;
/** Point layout of the current page*/
private LinearLayout mPointLinearLayout;
/**Whether automatic scroll*/
private boolean isAuto = false;
private int mIntervalTime = INTERVAL_TIME;
/** whether stop auto scroll when touching, default is true **/
private boolean stopScrollWhenTouch = true;
private boolean isStopByTouch = false;
private Handler mHandler;
/**point image resource id*/
private int mNormalPointImageResid;
private int mSelectPointImageResid;
private boolean isShowPoint = true;
private boolean isShowTitle = true;
/**previous page index*/
private Integer mPreviousItem = null;
private AutoSlideViewPageAdapter mAdapter;
private CustomDurationScroller scroller;
private double swipeScrollFactor = SCROOL_FACTOR;
private double autoScrollFactor = SCROOL_FACTOR;
private int pointWidth = LinearLayout.LayoutParams.WRAP_CONTENT;
private int pointMargin = 8;
public AutoSlideViewPager(Context context) {
super(context);
this.context = context;
initView();
}
public AutoSlideViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
initView();
}
private void initView() {
View.inflate(context, R.layout.auto_scroll_viewpage, this);
mViewPager = (ViewPager) this.findViewById(R.id.item_viewpage);
mDescriptionTextView = (TextView) this.findViewById(R.id.item_tv_desc);
mPointLinearLayout = (LinearLayout) this.findViewById(R.id.item_llayout_point);
mNormalPointImageResid = R.drawable.dot_normal;
mSelectPointImageResid = R.drawable.dot_focus;
mViewPager.setOnPageChangeListener(this);
setViewPagerScroller();
}
public void setAdapter(AutoSlideViewPageAdapter adapter) {
this.mAdapter = adapter;
mViewPager.setAdapter(adapter);
if (isShowPoint) {
mPointLinearLayout.removeAllViews();
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
pointWidth, pointWidth);
params.setMargins(pointMargin/2, pointMargin/2, pointMargin/2, pointMargin/2);
for(int i = 0; i < adapter.getPageCount(); i++) {
ImageView pointImage = new ImageView(context);
pointImage.setLayoutParams(params);
pointImage.setBackgroundResource(mNormalPointImageResid);
mPointLinearLayout.addView(pointImage);
}
}
mViewPager.setCurrentItem(mAdapter.getPageCount()* 100);
}
public void setPointWidthAndMargin(int width, int margin) {
this.pointMargin = margin;
this.pointWidth = width;
}
/**
* point image resource id
* @param normal
* @param select
*/
public void setPointImageResId(int normal, int select) {
this.mNormalPointImageResid = normal;
this.mSelectPointImageResid = select;
}
/**
* Set title of the current page
* @param charSequence
*/
public void setCurrentPageDescription(CharSequence charSequence) {
mDescriptionTextView.setText(charSequence);
}
/**
* Set page interactive time interval
* @param
*/
public void setIntervalTime(int intervalTime) {
this.mIntervalTime = intervalTime;
}
/**
* start auto slide
* @param
*/
public void startSlide() {
isAuto = true;
if (mHandler == null) {
mHandler = new MHandler();
}
removeMessages(WHAT);
sendMessage(WHAT, (long) (mIntervalTime + scroller.getDuration()/ autoScrollFactor * swipeScrollFactor));
}
/**
* stop auto slide
* Suggest to destroy at the interface between the time to stop
*/
public void stopSlide() {
isAuto = false;
if (mHandler != null) {
removeMessages(WHAT);
}
}
private void sendMessage(int what, long delayMillis) {
mHandler.sendEmptyMessageDelayed(what, delayMillis);
}
private void removeMessages(int what) {
mHandler.removeMessages(what);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (stopScrollWhenTouch) {
if (ev.getAction() == MotionEvent.ACTION_DOWN && isAuto) {
isStopByTouch = true;
stopSlide();
}
else if (ev.getAction() == MotionEvent.ACTION_UP && isStopByTouch) {
startSlide();
}
}
return super.dispatchTouchEvent(ev);
}
/**
* set whether stop auto scroll when touching, default is true
*
* @param stopScrollWhenTouch
*/
public void setStopScrollWhenTouch(boolean stopScrollWhenTouch) {
this.stopScrollWhenTouch = stopScrollWhenTouch;
}
public void setCurrentItem(int item, boolean smoothScroll) {
item = mViewPager.getCurrentItem() - getCurrentItem() + item;
mViewPager.setCurrentItem(item, smoothScroll);
stopSlide();
startSlide();
}
public int getCurrentItem() {
return mViewPager.getCurrentItem() % mAdapter.getPageCount();
}
/**
* Whether the display point images
* @param isShowPoint
*/
public void setShowPoint(boolean isShowPoint) {
this.isShowPoint = isShowPoint;
}
public void setShowTitle(boolean isShowTitle) {
this.isShowTitle = isShowTitle;
}
/**
* set ViewPager scroller to change animation duration when sliding
*/
private void setViewPagerScroller() {
try {
Field scrollerField = ViewPager.class.getDeclaredField("mScroller");
scrollerField.setAccessible(true);
Field interpolatorField = ViewPager.class.getDeclaredField("sInterpolator");
interpolatorField.setAccessible(true);
scroller = new CustomDurationScroller(getContext(), (Interpolator)interpolatorField.get(null));
scrollerField.set(mViewPager, scroller);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* set the factor by which the duration of sliding animation will change while swiping
*/
public void setSwipeScrollDurationFactor(double scrollFactor) {
scroller.setScrollDurationFactor(scrollFactor);
swipeScrollFactor = scrollFactor;
}
/**
* set the factor by which the duration of sliding animation will change while auto scrolling
*/
public void setAutoScrollDurationFactor(double scrollFactor) {
autoScrollFactor = scrollFactor;
}
@Override
public void onPageScrollStateChanged(int state) {
}
@Override
public void onPageScrolled(int i, float v, int j) {
}
@Override
public void onPageSelected(int position) {
if (isShowPoint) {
changePointImageState(mAdapter.getPosition(position), true);
if(null != mPreviousItem)
changePointImageState(mAdapter.getPosition(mPreviousItem), false);
mPreviousItem = position;
}
if(isShowTitle) {
setCurrentPageDescription(mAdapter.getPageTitle(position));
}
}
private void changePointImageState(int index, boolean isSelect) {
ImageView poiImageView = (ImageView) mPointLinearLayout.getChildAt(index);
int resId = isSelect ? mSelectPointImageResid : mNormalPointImageResid;
poiImageView.setBackgroundResource(resId);
}
@SuppressLint("HandlerLeak")
private class MHandler extends Handler{
@Override
public void handleMessage(Message msg) {
if (isAuto) {
scroller.setScrollDurationFactor(autoScrollFactor);
mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1, true);
scroller.setScrollDurationFactor(swipeScrollFactor);
AutoSlideViewPager.this.sendMessage(WHAT, mIntervalTime + scroller.getDuration());
}
}
}
}