Android实现banner自动和手动轮换

之前在网上看了很多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];
            }
        };
    }
}



今晚有点事,晚点在写

先奉上代码


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值