之前在网上看了很多banner的demo,但是大多是只能自动轮换而不能手动轮换(或者说是最后一张轮换不到第一张)
在参考http://blog.csdn.net/a553181867/article/details/52734261的作品下,我以此为基础做了改进。
好,那我现在就先上图
改进的思想:
然后就是判断当页面1跑到页面5的时候
让第一个页面5跳转到倒数第二的页面5.
主界面xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="example"
android:textSize="24sp"
android:layout_marginTop="5dp"
android:layout_marginBottom="40dp"/>
<com.chenyu.library.bannerViewPager.BannerViewPager
android:id="@+id/banner"
android:layout_width="match_parent"
android:layout_height="200dp">
</com.chenyu.library.bannerViewPager.BannerViewPager>
</LinearLayout>
BannerViewPager
public class BannerViewPager extends FrameLayout implements ViewPager.OnPageChangeListener {
private ViewPager mViewPager;
private ViewPagerIndicator mIndicator;
private ViewPagerAdapter mAdapter;
private Context mContext;
private int mCurrentPosition;
public String TAG = "CJW";
public JungeValueChange jungle;
public JungeValue jungleValue;
public boolean ChangOrNot;
//viewpager's rolling state
private int mViewPagerScrollState;
//by default,auto-rolling is on.
private boolean isAutoRolling = true;
//the interval between rollings
private int mAutoRollingTime = 2000;
private int mReleasingTime = 0;
private static final int MESSAGE_AUTO_ROLLING = 0X1001;
private static final int MESSAGE_AUTO_ROLLING_CANCEL = 0X1002;
private static final int MESSAGE_ININTIAL_VIEW = 0X1003;
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_AUTO_ROLLING:
if (mCurrentPosition == mAdapter.getCount() - 2) {
mViewPager.setCurrentItem(1, false);
} else {
mViewPager.setCurrentItem(mCurrentPosition + 1, true);
}
postDelayed(mAutoRollingTask, mAutoRollingTime);
break;
case MESSAGE_AUTO_ROLLING_CANCEL:
if (mCurrentPosition == mAdapter.getCount() - 1) {
mViewPager.setCurrentItem(1, true);
} else if (mCurrentPosition == 0) {
mViewPager.setCurrentItem(mAdapter.getCount() - 2, true);
}
post(mAutoRollingTask);
break;
case MESSAGE_ININTIAL_VIEW:
mViewPager.setCurrentItem(1, false);
break;
}
}
};
public BannerViewPager(Context context) {
this(context, null);
}
public BannerViewPager(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public BannerViewPager(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext = context;
initViews();
}
private void initViews() {
//initialize the viewpager
mViewPager = new ViewPager(mContext);
ViewPager.LayoutParams lp = new ViewPager.LayoutParams();
lp.width = ViewPager.LayoutParams.MATCH_PARENT;
lp.height = ViewPager.LayoutParams.MATCH_PARENT;
mViewPager.setLayoutParams(lp);
jungle = new JungeValueChange();
jungleValue = new JungeValue();
jungle.addListener(jungleValue);
//initialize the indicator
mIndicator = new ViewPagerIndicator(mContext);
FrameLayout.LayoutParams indicatorlp = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
indicatorlp.gravity = Gravity.BOTTOM | Gravity.CENTER;
indicatorlp.bottomMargin = 20;
mIndicator.setLayoutParams(indicatorlp);
mHandler.sendEmptyMessage(MESSAGE_ININTIAL_VIEW);
}
public void setAutoRolling(boolean isAutoRolling) {
this.isAutoRolling = isAutoRolling;
}
public void setAutoRollingTime(int time) {
this.mAutoRollingTime = time;
}
public void setAdapter(ViewPagerAdapter adapter) {
mViewPager.setAdapter(adapter);
mViewPager.addOnPageChangeListener(this);
mAdapter = adapter;
mAdapter.registerSubscriber(new DataSetSubscriber() {
@Override
public void update(int count) {
mIndicator.setItemCount(count);
}
});
//add the viewpager and the indicator to the container.
addView(mViewPager);
addView(mIndicator);
//start the auto-rolling task if needed
if (isAutoRolling) {
postDelayed(mAutoRollingTask, mAutoRollingTime);
}
}
/**
* If the current page is being dragged by the user,this method will be invoke.
* And then it will call {@link ViewPagerIndicator#setPositionAndOffset}.
*
* @param position Position index of the first page currently being displayed.
* @param offset Value from [0, 1) indicating the offset from the page at position.
*/
private void setIndicator(int position, float offset) {
mIndicator.setPositionAndOffset(position, offset);
}
/**
* This runnable decides the viewpager should roll to next page or wait.
*/
private Runnable mAutoRollingTask = new Runnable() {
@Override
public void run() {
int now = (int) System.currentTimeMillis();
int timediff = mAutoRollingTime;
if (mReleasingTime != 0) {
timediff = now - mReleasingTime;
}
if (mViewPagerScrollState == ViewPager.SCROLL_STATE_IDLE) {
//if user's finger just left the screen,we should wait for a while.
if (timediff >= mAutoRollingTime * 0.8) {
mHandler.sendEmptyMessage(MESSAGE_AUTO_ROLLING);
} else {
mHandler.sendEmptyMessage(MESSAGE_AUTO_ROLLING_CANCEL);
}
} else if (mViewPagerScrollState == ViewPager.SCROLL_STATE_DRAGGING) {
mHandler.sendEmptyMessage(MESSAGE_AUTO_ROLLING_CANCEL);
} else if (mViewPagerScrollState == ViewPager.SCROLL_STATE_SETTLING) {
mHandler.sendEmptyMessage(MESSAGE_AUTO_ROLLING_CANCEL);
}
}
};
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
setIndicator(position, positionOffset);
}
//页面转到哪里
@Override
public void onPageSelected(int position) {
mCurrentPosition = position;
if (mCurrentPosition == 0){
mViewPager.setCurrentItem(mAdapter.getCount() - 2, true);
}else if (mCurrentPosition == mAdapter.getCount() - 1){
mViewPager.setCurrentItem(1, true);
}
}
//记录当页面滑动时状态的变化
@Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_DRAGGING) {
mViewPagerScrollState = ViewPager.SCROLL_STATE_DRAGGING;
} else if (state == ViewPager.SCROLL_STATE_IDLE) {
mReleasingTime = (int) System.currentTimeMillis();
mViewPagerScrollState = ViewPager.SCROLL_STATE_IDLE;
} else if (state == ViewPager.SCROLL_STATE_SETTLING) {
mViewPagerScrollState = ViewPager.SCROLL_STATE_DRAGGING;
}
}
/**
* Save the state of this BannerViewPager.The current position will be saved.
*
* @return Parcelable
*/
@Override
protected Parcelable onSaveInstanceState() {
Parcelable parcelable = super.onSaveInstanceState();
SavedState ss = new SavedState(parcelable);
ss.currentPosition = mCurrentPosition;
return ss;
}
/**
* Restore the BannerViewPager from the previous state.
*
* @param state
*/
@Override
protected void onRestoreInstanceState(Parcelable state) {
SavedState ss = (SavedState) state;
super.onRestoreInstanceState(ss.getSuperState());
mViewPager.setCurrentItem(ss.currentPosition);
}
static class SavedState extends BaseSavedState {
int currentPosition;
public SavedState(Parcel source) {
super(source);
currentPosition = source.readInt();
}
public SavedState(Parcelable superState) {
super(superState);
}
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeInt(currentPosition);
}
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
@Override
public SavedState createFromParcel(Parcel source) {
return new SavedState(source);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
今晚有点事,晚点在写