viewpager实现花式图片轮播

效果图

viewpager实现花式图片轮播_第1张图片

首先,让我们了解下什么是viewpager:

这个大致意思是:这个布局管理器允许用户左右翻转并传递页面的数据,你想要的视图可以通过pagerAdapter来实现。

布局文件:



    

    

布局文件很简单,只有个用于展示图片的viewpager和用于同步展示图片的radioGroup

pagerAdapter

pagerAdapter是android.support.v4包中的类,它的子类有fragmentPagerAdapter、 fragmentStatePagerAdapter,这两个adapter都是fragment的适配器,用于实现fragment的滑动效果。

 PagerAdapter pagerAdapter = new PagerAdapter() {
        @Override
        public int getCount() {
            return Integer.MAX_VALUE;
//                return images.length;
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            //判断当前要显示的画面
            return view == object;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            position = position % images.length;
            ImageView imageView = new ImageView(ViewPagerActivity.this);
            imageView.setImageResource(images[position]);
            imageView.setScaleType(ImageView.ScaleType.FIT_XY);
            container.addView(imageView);
            return imageView;
        }

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

pagerAdapter内有四个方法:

getCount():要滑动的图片数量,这里用Integer.MAX_VALUE,目的是为了实现无限轮播。

isViewFromObject():这个方法用于判断当前要显示的图片。

instantiateItem():调用这个方法用于图片初始化,将要显示的图片放到container中缓存,viewpager的setOffscreenPageLimit()方法用于设置缓存图片的数量。

destroyItem():当滑动的图片超出缓存范围,就会销毁缓存的图片。

PageTransformer

viewPager的pageTransformer是滑动图片的一个动画效果,viewPager提供setPageTransformer()这个方法用于设置动画。

 public class PageTransform implements ViewPager.PageTransformer {
        @Override
        public void transformPage(View view, float position) {
            if (position < -1) {
                //透明度
                view.setAlpha(mMinAlpha);
                //旋转
                view.setRotation(mMaxRotate * -1);
                view.setPivotX(view.getWidth());
                view.setPivotY(view.getHeight());
            } else if (position <= 1) {
                if (position < 0) {
                    //position是0到-1的变化,1+position就是从1到0的变化
                    //(1 - mMinAlpha) * (1 + position)就是(1 - mMinAlpha)到0的变化
                    //再加上一个mMinAlpha,就变为1到mMinAlpha的变化。
                    float factor = mMinAlpha + (1 - mMinAlpha) * (1 + position);
                    view.setAlpha(factor);

                    view.setRotation(mMaxRotate * position);
                    //position为width/2到width的变化
                    view.setPivotX(view.getWidth() * 0.5f * (1 - position));
                    view.setPivotY(view.getHeight());
                } else {
                    //minAlpha到1的变化
                    float factor = mMinAlpha + (1 - mMinAlpha) * (1 - position);
                    view.setAlpha(factor);

                    view.setRotation(mMaxRotate * position);
                    view.setPivotX(view.getWidth() * 0.5f * (1 - position));
                    view.setPivotY(view.getHeight());
                }
            } else {
                view.setAlpha(mMinAlpha);

                view.setRotation(mMaxRotate);
                view.setPivotX(0);
                view.setPivotY(view.getHeight());
            }
        }
    }

小圆圈的设置

 private void initRadioButton(int length) {
        for (int i = 0; i < length; i++) {
            ImageView imageView = new ImageView(ViewPagerActivity.this);
            imageView.setImageResource(R.drawable.rg_selector);
            imageView.setPadding(20, 0, 0, 0);
            radioGroup.addView(imageView, ViewGroup.LayoutParams.WRAP_CONTENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
            radioGroup.getChildAt(0).setEnabled(false);
        }
    }

length就是轮播图片的数量。

rg_selctor:                state_enabled:是否处于可用状态



    
    

rb_default:


    
    

rb_select:


    
    

pager改变时的监听

ViewPager.OnPageChangeListener onPageChangeListener = new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            index = position;
            setCurrentDot(index % images.length);
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    };
 private void setCurrentDot(int i) {
        if (radioGroup.getChildAt(i) != null) {
            //当前按钮不可改变
            radioGroup.getChildAt(i).setEnabled(false);
        }
        if (radioGroup.getChildAt(preIndex) != null) {
            //上个按钮可以改变
            radioGroup.getChildAt(preIndex).setEnabled(true);
            //当前位置变为上一个,继续下次轮播
            preIndex = i;
        }
    }

轮播时间设置

 timer.schedule(new TimerTask() {
            @Override
            public void run() {
                if (isContinue) {
                    handler.sendEmptyMessage(1);
                }
            }
        }, 2000, 2000);

schedule()方法第三个参数是图片轮播完后多久再次执行run()方法,这里设置两秒,跟延时一致,图片会完美轮播下去。

Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 1:
                    index++;
                    viewPager.setCurrentItem(index);
            }
        }
    };

handler调用handleMessage()方法处理消息。

完整代码

public class ViewPagerActivity extends AppCompatActivity {

    private ViewPager viewPager;
    private int images[] = {R.drawable.img01, R.drawable.img02, R.drawable.img03,
            R.drawable.img04, R.drawable.img05, R.drawable.img06};
    private RadioGroup radioGroup;
    //当前索引位置以及上一个索引位置
    private int index;
    private int preIndex;
    private Timer timer = new Timer();
    //是否需要轮播标志
    private boolean isContinue = true;

    private static final float DEFAULT_MIN_ALPHA = 0.3f;
    private float mMinAlpha = DEFAULT_MIN_ALPHA;

    private static final float DEFAULT_MAX_ROTATE = 15.0f;
    private float mMaxRotate = DEFAULT_MAX_ROTATE;

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

        viewPager = (ViewPager) findViewById(R.id.view_Pager);
        radioGroup = (RadioGroup) findViewById(R.id.radio_group);
        //设置page之间间距
        viewPager.setPageMargin(30);
        //设置缓存的页面数量
        viewPager.setOffscreenPageLimit(3);
        viewPager.setAdapter(pagerAdapter);
        viewPager.addOnPageChangeListener(onPageChangeListener);
        viewPager.setPageTransformer(true, new PageTransform());
        viewPager.setCurrentItem(images.length * 100);
        initRadioButton(images.length);

        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                if (isContinue) {
                    handler.sendEmptyMessage(1);
                }
            }
        }, 2000, 2000);
    }

    PagerAdapter pagerAdapter = new PagerAdapter() {
        @Override
        public int getCount() {
            return Integer.MAX_VALUE;
//                return images.length;
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            //判断当前要显示的画面
            return view == object;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            position = position % images.length;
            ImageView imageView = new ImageView(ViewPagerActivity.this);
            imageView.setImageResource(images[position]);
            imageView.setScaleType(ImageView.ScaleType.FIT_XY);
            container.addView(imageView);
            return imageView;
        }

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

    /**
     * [-Infinity,-1)(1,+Infinity][-1,1]
     * 三个区间,对于前两个,拿我们的页面上目前显示的3个Page来说,前两个分别对应左右两个露出一点的Page,
     * 那么对于alpha值,只需要设置为最小值即可
     * 

* [-1,1]第一页->第二页这个过程来说,主要看position的变化 * 页1的position变化为:从0到-1, 页2的position变化为:从1到0 * 第一页到第二页,实际上就是左滑,第一页到左边,第二页成为currentItem到达中间, * 那么对应alpha的变化应该是:页1到左边,对应alpha应该是:1到minAlpha * 页2到中间,成为currentItem,对应alpha应该是:minAlpha到1 */ public class PageTransform implements ViewPager.PageTransformer { @Override public void transformPage(View view, float position) { if (position < -1) { //透明度 view.setAlpha(mMinAlpha); //旋转 view.setRotation(mMaxRotate * -1); view.setPivotX(view.getWidth()); view.setPivotY(view.getHeight()); } else if (position <= 1) { if (position < 0) { //position是0到-1的变化,1+position就是从1到0的变化 //(1 - mMinAlpha) * (1 + position)就是(1 - mMinAlpha)到0的变化 //再加上一个mMinAlpha,就变为1到mMinAlpha的变化。 float factor = mMinAlpha + (1 - mMinAlpha) * (1 + position); view.setAlpha(factor); view.setRotation(mMaxRotate * position); //position为width/2到width的变化 view.setPivotX(view.getWidth() * 0.5f * (1 - position)); view.setPivotY(view.getHeight()); } else { //minAlpha到1的变化 float factor = mMinAlpha + (1 - mMinAlpha) * (1 - position); view.setAlpha(factor); view.setRotation(mMaxRotate * position); view.setPivotX(view.getWidth() * 0.5f * (1 - position)); view.setPivotY(view.getHeight()); } } else { view.setAlpha(mMinAlpha); view.setRotation(mMaxRotate); view.setPivotX(0); view.setPivotY(view.getHeight()); } } } private void initRadioButton(int length) { for (int i = 0; i < length; i++) { ImageView imageView = new ImageView(ViewPagerActivity.this); imageView.setImageResource(R.drawable.rg_selector); imageView.setPadding(20, 0, 0, 0); radioGroup.addView(imageView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); radioGroup.getChildAt(0).setEnabled(false); } } ViewPager.OnPageChangeListener onPageChangeListener = new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { index = position; setCurrentDot(index % images.length); } @Override public void onPageScrollStateChanged(int state) { } }; private void setCurrentDot(int i) { if (radioGroup.getChildAt(i) != null) { //当前按钮不可改变 radioGroup.getChildAt(i).setEnabled(false); } if (radioGroup.getChildAt(preIndex) != null) { //上个按钮可以改变 radioGroup.getChildAt(preIndex).setEnabled(true); //当前位置变为上一个,继续下次轮播 preIndex = i; } } Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 1: index++; viewPager.setCurrentItem(index); } } }; }

 

你可能感兴趣的:(viewpager实现花式图片轮播)