Android-自动轮播的ViewPager+滑动指示器

先给大家上效果图

项目运行
这里写图片描述
项目结构
这里写图片描述

项目思路

问题1: 左右无限滑

    在PagerAdapt的getCount方法里给上一个很大的数
        public int getCount() {
            return Integer.MAX_VALUE;
        }
    然后把设置item项设置到一个中间的位置
        int diff = Integer.MAX_VALUE /2 % mData.size();
        mPager.setCurrentItem(Integer.MAX_VALUE /2 - diff);

问题二: 防止position过大 引起下标越界

    在所有需要处理position值得地方加上
        position = position % mData.size();

问题三:自动轮播

    使用Thread或者使用Handler都可以,原理就是隔一段时间把pager的item项+1
    我这用的一个自定的Runnable,写了一个停止方法和开始方法
        class AutoScrollTask implements Runnable{

            @Override
            public void run() {
                int item = mPager.getCurrentItem();
                mPager.setCurrentItem(item + 1);
                startTask();        
            }

            public void startTask(){
                mPager.postDelayed(this, 2000); 
            }

            public void stopTask(){
                mPager.removeCallbacks(this);
            }

        }

问题四:停止轮播和重新开始轮播

    去监听pager,当发生DOWN事件的时候去停止轮播,UP事件的时候就去重新轮播
        final AutoScrollTask task = new AutoScrollTask();
        task.startTask();

        mPager.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {

                switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    task.stopTask();
                    break;
                case MotionEvent.ACTION_UP:
                    task.startTask();
                    break;
                }


                return false;
            }
        });

项目代码

代码 AutoCarousel 类

    public class AutoCarousel extends RelativeLayout {

    private List<Bitmap> mData; // 数据源 

    private int mIndicatorHeight; // 滑动指示器高度

    private ViewPager mPager;   // 轮播的ViewPager
    private LinearLayout mIndicator;  // 指示器容器控件

    public AutoCarousel(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public AutoCarousel(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public AutoCarousel(Context context) {
        super(context);
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);   
        mIndicatorHeight = mIndicator.getHeight();
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
    }


    /** 初始化数据 只用当外界调用这个方法一切才会开始 */
    public void initView(List<Bitmap> T) {  
        mData = T;  
        if (mData != null && mData.size() != 0) {       

        View.inflate(getContext(), R.layout.auto_carousel, this);  

        mPager = (ViewPager) findViewById(R.id.lv_auto_carousel);
        mIndicator = (LinearLayout) findViewById(R.id.ll_auto_carousel_indicator);

        mIndicator.setGravity(Gravity.CENTER);
        // 轮播
        mPager.setAdapter(new AutoAdapter());
        // 添加指示器
        for (int i = 0; i < mData.size(); i++) {    
            IndicatorView indicatorView = new IndicatorView(getContext());
            mIndicator.addView(indicatorView );
        }

        // 监听滑动,目的是为了同步指示器的改变
        mPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

            @Override
            public void onPageSelected(int position) {
                position = position % mData.size();
                for (int i = 0; i < mData.size(); i++) {
                    IndicatorView view= (IndicatorView) mIndicator.getChildAt(i);
                    view.changeColor(Color.GRAY);
                    if (position == i) {
                        view.changeColor(Color.RED);
                    }

                }   
            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {

            }

            @Override
            public void onPageScrollStateChanged(int arg0) {

            }
        });

        // 设置偏移,目的是为了使item 刚好处于第0项的位置
        int diff = Integer.MAX_VALUE /2 % mData.size(); 
        mPager.setCurrentItem(Integer.MAX_VALUE /2 - diff);

        // 开始轮播
        final AutoScrollTask task = new AutoScrollTask();
        task.startTask();
        // 停止轮播和重新开始轮播的处理 
        mPager.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {

                switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    task.stopTask();
                    break;
                case MotionEvent.ACTION_UP:
                    task.startTask();
                    break;
                }


                return false;
            }
        });

        }
    }

    /** 适配器 */
    class AutoAdapter extends PagerAdapter{

        @Override
        public int getCount() {
            return Integer.MAX_VALUE;
        }

        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            return arg0 == arg1;
        }


        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            position = position % mData.size();
            ImageView image = new ImageView(getContext());  //fitXY
            image.setImageBitmap(mData.get(position));
            image.setScaleType(ScaleType.FIT_XY);
            container.addView(image);
            return image;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }


    }
    /** 自动轮播 */
    class AutoScrollTask implements Runnable{

        @Override
        public void run() {
            int item = mPager.getCurrentItem();
            mPager.setCurrentItem(item + 1);
            startTask();        
        }

        public void startTask(){
            mPager.postDelayed(this, 2000);

        }

        public void stopTask(){
            mPager.removeCallbacks(this);
        }

    }
    /** 指示器 */
    class IndicatorView extends View{

        Paint paint;
        public IndicatorView(Context context) {
            super(context);

            paint = new Paint();
            paint.setColor(Color.GRAY);
        }

        public void changeColor(int color){
            paint.setColor(color);
            invalidate();
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            setMeasuredDimension(16, mIndicatorHeight);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            canvas.drawCircle(8, mIndicatorHeight/2, 4, paint);
        }

    }

}

代码 MainActivity 类

    public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        AutoCarousel auto = (AutoCarousel) findViewById(R.id.re);

        List<Bitmap> T = new ArrayList<Bitmap>();

        Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.img1);
        Bitmap bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.img2);
        Bitmap bitmap3 = BitmapFactory.decodeResource(getResources(), R.drawable.img3);
        Bitmap bitmap4 = BitmapFactory.decodeResource(getResources(), R.drawable.img4);

        T.add(bitmap1);
        T.add(bitmap2);
        T.add(bitmap3);
        T.add(bitmap4);

        auto.initView(T);

    }
}

代码 activity_main.xml 文件

    <RelativeLayout 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">

        <com.xuan.autocarousel.AutoCarousel
            android:id="@+id/re"
            android:layout_width="match_parent"
            android:layout_height="200dp"/>  

    </RelativeLayout>

代码 auto_carousel.xml 文件

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="150dp">

        <android.support.v4.view.ViewPager
            android:id="@+id/lv_auto_carousel"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

        <LinearLayout
            android:id="@+id/ll_auto_carousel_indicator"
            android:layout_alignParentBottom="true"
            android:layout_width="match_parent"
            android:orientation="horizontal"
            android:background="#6000"
            android:layout_height="40dp"/>

    </RelativeLayout>

运行项目

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值