美文网首页Android专题Android控件使用篇
用ViewPager实现轮播图:图片无限轮播+动态切换+小圆点切

用ViewPager实现轮播图:图片无限轮播+动态切换+小圆点切

作者: 千夜零一 | 来源:发表于2020-09-21 11:48 被阅读0次

    引言

      现如今很多app中都有可以轮播的图片墙,虽然github上有很多的开源库可以使用,但不引用库你会不会实现Banner轮播图?这就不得不推出ViewPager了,本期我们就来利用ViewPager实现各种图片轮播,从0到1,从基础版到升级版再到完整版。给你的app做图片轮播Banner,看这一篇就够了!

    效果预览

    轮播Banner图.gif

    介绍

    README:我做了三个ViewPager的示例,分别适用于以下场景:

    第一个:切换有限个fragment。

    第二个:简单的图片无限轮播。

    第三个:图片无限轮播+动态切换+小圆点切换+透明标题(功能齐全)。

    用法

    第一步:主布局文件

    主activity的layout布局文件:
    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/darker_gray"
        tools:ignore="MissingConstraints">
    
        <androidx.core.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <androidx.constraintlayout.widget.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">
    
                <androidx.viewpager.widget.ViewPager
                    android:background="@color/white"
                    android:id="@+id/view_pager1"
                    android:layout_margin="5dp"
                    android:layout_width="match_parent"
                    android:layout_height="250dp"
                    app:layout_constraintTop_toTopOf="parent" />
    
                <androidx.viewpager.widget.ViewPager
                    android:background="@color/white"
                    android:id="@+id/view_pager2"
                    android:layout_width="match_parent"
                    android:layout_height="250dp"
                    android:layout_margin="5dp"
                    app:layout_constraintTop_toBottomOf="@+id/view_pager1" />
    
                <FrameLayout
                    app:layout_constraintTop_toBottomOf="@id/view_pager2"
                    android:layout_width="match_parent"
                    android:background="@color/white"
                    android:layout_margin="5dp"
                    android:layout_height="250dp">
    
                    <androidx.viewpager.widget.ViewPager
                        android:id="@+id/view_pager3"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent" />
    
                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="35dip"
                        android:layout_gravity="bottom"
                        android:background="#33000000"
                        android:gravity="center"
                        android:orientation="vertical">
    
                        <TextView
                            android:id="@+id/title"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="图片标题"
                            android:textColor="@android:color/white" />
    
                        <LinearLayout
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_marginTop="3dip"
                            android:orientation="horizontal">
    
                            <View
                                android:id="@+id/dot_0"
                                android:layout_width="5dip"
                                android:layout_height="5dip"
                                android:layout_marginLeft="2dip"
                                android:layout_marginRight="2dip"
                                android:background="@drawable/dot_focused" />
    
                            <View
                                android:id="@+id/dot_1"
                                android:layout_width="5dip"
                                android:layout_height="5dip"
                                android:layout_marginLeft="2dip"
                                android:layout_marginRight="2dip"
                                android:background="@drawable/dot_normal" />
    
                            <View
                                android:id="@+id/dot_2"
                                android:layout_width="5dip"
                                android:layout_height="5dip"
                                android:layout_marginLeft="2dip"
                                android:layout_marginRight="2dip"
                                android:background="@drawable/dot_normal" />
    
                        </LinearLayout>
    
                    </LinearLayout>
    
                </FrameLayout>
            </androidx.constraintlayout.widget.ConstraintLayout>
        </androidx.core.widget.NestedScrollView>
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    第二步:第一个ViewPager的布局文件(其他2,3不用此)

    layout下创建文件viewpager_view_item1
    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout 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"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        tools:ignore="MissingConstraints">
    
        <ImageView
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            android:id="@+id/viewpager_img"
            android:src="@drawable/lunbo1"
            android:layout_width="match_parent"
            android:scaleType="fitCenter"
            android:layout_height="200dp" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    创建三个fragment对应的三个布局文件:R.layout.viewpager_view_item1,……2,……3。

    三个类似布局,唯一不同就是引用android:src="@drawable/lunbo1"图片资源不同。
    图片名称分别是lunbo1,lunbo2,lunbo3

    第三步:创建viewPager的适配器类(看清楚再使用,3个适配器类分别对应3个主布局中的viewPager1,viewPager2,viewPager3)

    第1个viewPager的适配器类:
    public class ViewPagerAdapterOne extends PagerAdapter {
        List<View> viewPagerList;
    
        public ViewPagerAdapterOne(List<View> imgList) {
            this.viewPagerList = imgList;
        }
    
        @Override
        public int getCount() {
            return viewPagerList.size();
        }
    
        @Override
        public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
            return view == object;
        }
    
        @NonNull
        @Override
        public Object instantiateItem(@NonNull ViewGroup view, int position) {
            view.addView(viewPagerList.get(position));
            return viewPagerList.get(position);
        }
    
        @Override
        public void destroyItem(@NonNull ViewGroup view, int position, @NonNull Object object) {
            view.removeView(viewPagerList.get(position));
        }
    
    }
    
    第2个viewPager的适配器类:
    public class ViewPagerAdapterTwo extends PagerAdapter {
        private ArrayList<ImageView> listviews;
    
        public ViewPagerAdapterTwo(ArrayList<ImageView> views) {
            this.listviews = views;
        }
    
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
    
            if (listviews.get(position % listviews.size()).getParent() != null) {
                container.removeView(listviews.get(position % listviews.size()));
            }
            container.addView(listviews.get(position % listviews.size()), 0);
    
            return listviews.get(position % listviews.size());
        }
        @Override
        public int getCount() {
            return Integer.MAX_VALUE;
        }
        @Override
        public boolean isViewFromObject(View view, Object o) {
            return view == o;
        }
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
        }
    
    }
    
    第3个viewPager的适配器类:
    public class ViewPagerAdapterThree extends PagerAdapter {
        ArrayList<ImageView> images;
    
        private int maxValue = Integer.MAX_VALUE;
    
    
        public ViewPagerAdapterThree(ArrayList<ImageView> images) {
            this.images = images;
        }
    
        @Override
        public int getCount() {
            return maxValue;
        }
    
        //是否是同一张图片
        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            return arg0 == arg1;
        }
    
        @Override
        public Object instantiateItem(ViewGroup view, int position) {
            // 在父布局中添加View前先判断父布局中是否已经存在View
            // 如果父布局中已经有了需要在添加前做remove操作
            // 否则会报错Android-The specified child already has a parent. You must call removeView() on the child's parent first.
            int currentPosition = (position % images.size());
            ImageView iv = images.get(currentPosition);
            if (iv.getParent()!=null){
                ((ViewPager)iv.getParent()).removeView(iv);
            }
            view.addView(iv);
            return iv;
        }
    
        @Override
        public void destroyItem(ViewGroup view, int position, Object object) {
    
        }
    }
    

    第四步:activity中使用

    //viewpager使用实现轮播图
    public class Case8 extends AppCompatActivity {
        //初始化viewpager1
        private ViewPager viewPager1;
        private ViewPagerAdapterOne bannerAdapter;
        private ArrayList<View> pageviewList;
        //初始化viewpager2
        private ViewPager viewPager2;
        private ArrayList<ImageView> listviews;
        private ViewPagerAdapterTwo viewPagerAdapterTwo;
        int[] pics = {R.drawable.lunbo1, R.drawable.lunbo2, R.drawable.lunbo3};
        @SuppressLint("HandlerLeak")
        private MyHandler myHandler = new MyHandler();
        //初始化viewpager3
        private ViewPager viewPager3;
        private int imageIds[];
        private String[] titles;
        private ArrayList<ImageView> images;
        private ArrayList<View> dots;
        private TextView title;
        private ViewPagerAdapterThree viewPagerAdapterThree;
        private int oldPosition = 0;//记录上一次点的位置
        private int currentItem; //当前页面
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_case8);
            initViewPager1();  //简单切换图片
            inintViewPager2();  //图片动态切换
            initViewPager3();  //切换+动态+小点+标题
    
        }
    
        private void initViewPager1() {
            viewPager1 = findViewById(R.id.view_pager1);
            //查找布局文件用LayoutInflater.inflate
            LayoutInflater inflater = getLayoutInflater();
            View view1 = inflater.inflate(R.layout.viewpager_view_item1, null);
            View view2 = inflater.inflate(R.layout.viewpager_view_item2, null);
            View view3 = inflater.inflate(R.layout.viewpager_view_item3, null);
    
            //将view装入数组
            pageviewList = new ArrayList<View>();
            pageviewList.add(view1);
            pageviewList.add(view2);
            pageviewList.add(view3);
    
            //绑定适配器
            bannerAdapter = new ViewPagerAdapterOne(pageviewList);
            viewPager1.setAdapter(bannerAdapter);
        }
    
        private void inintViewPager2() {
            viewPager2 = findViewById(R.id.view_pager2);
            //处理
            listviews = new ArrayList<ImageView>();
            for (int i = 0; i < pics.length; i++) {
                ImageView imageView = new ImageView(this);
                ViewGroup.LayoutParams viewPagerImageViewParams = new ViewGroup.LayoutParams(
                        ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
                imageView.setLayoutParams(viewPagerImageViewParams);
                imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
                imageView.setImageResource(pics[i]);
                listviews.add(imageView);
            }
            viewPagerAdapterTwo = new ViewPagerAdapterTwo(listviews);
            viewPager2.setAdapter(viewPagerAdapterTwo);
            viewPager2.setCurrentItem(1);
            myHandler.sendEmptyMessageDelayed(0, 1500);// 间隔一秒切换一次
        }
    
        //viewPager2使用
        @SuppressLint("HandlerLeak")
        class MyHandler extends Handler {
            @Override
            public void handleMessage(@NonNull Message msg) {
                viewPager2.setCurrentItem(viewPager2.getCurrentItem() + 1);
                myHandler.sendEmptyMessageDelayed(0, 2000);
            }
        }
    
        private void initViewPager3() {
    
    
            //图片ID
            imageIds = new int[]{
                    R.drawable.lunbo1,
                    R.drawable.lunbo2,
                    R.drawable.lunbo3
            };
            //图片标题
            titles = new String[]{
                    "巩俐不低俗,我就不能低俗",
                    "乐视网TV版大派送",
                    "热血屌丝的反杀"
            };
            //显示的图片
            images = new ArrayList<ImageView>();
            for (int i = 0; i < imageIds.length; i++) {
                ImageView imageView = new ImageView(this);
                imageView.setBackgroundResource(imageIds[i]);
    
                images.add(imageView);
            }
            //显示的点
            dots = new ArrayList<View>();
            dots.add(findViewById(R.id.dot_0));
            dots.add(findViewById(R.id.dot_1));
            dots.add(findViewById(R.id.dot_2));
    
            title = (TextView) findViewById(R.id.title);
            title.setText(titles[0]);
    
            viewPager3 = (ViewPager) findViewById(R.id.view_pager3);
    
            viewPagerAdapterThree = new ViewPagerAdapterThree(images);
    
            viewPager3.setAdapter(viewPagerAdapterThree);
    
            viewPager3.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
                @Override
                public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    
                }
    
                @Override
                public void onPageSelected(int position) {
                    int currentPosition = position % (images.size());
                    title.setText(titles[currentPosition]);
                    dots.get(oldPosition).setBackgroundResource(R.drawable.dot_normal);
                    dots.get(currentPosition).setBackgroundResource(R.drawable.dot_focused);
    
                    oldPosition = currentPosition;
                    currentItem = currentPosition;
                }
    
                @Override
                public void onPageScrollStateChanged(int state) {
    
                }
            });
            handler.sendEmptyMessage(1);
            initViewPagerTouchEvent();
            setFirstLocation();
        }
    
        @SuppressLint("HandlerLeak")
        private Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                //设置当前页面
                currentItem = viewPager3.getCurrentItem();
                viewPager3.setCurrentItem(currentItem + 1);
                handler.sendEmptyMessageDelayed(1, 2000);
            }
        };
    
        @Override
        protected void onStop() {
            super.onStop();
        }
    
        @SuppressLint("ClickableViewAccessibility")
        private void initViewPagerTouchEvent() {
            viewPager3.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    switch (event.getAction()) {
                        case MotionEvent.ACTION_DOWN: {
                            //按下
                            handler.removeCallbacksAndMessages(null);
                        }
                        break;
    
                        case MotionEvent.ACTION_UP: {
                            //抬起
                            handler.sendEmptyMessageDelayed(1, 2000);
    
                        }
                        break;
                    }
                    return false;
                }
            });
        }
    
        private void setFirstLocation() {
            // mTvPagerTitle.setText(mImageTitles[previousPosition]);
            // 把ViewPager设置为默认选中Integer.MAX_VALUE / 2,从十几亿次开始轮播图片,达到无限循环目的;
            int m = (Integer.MAX_VALUE / 2) % images.size();
            int currentPosition = Integer.MAX_VALUE / 2 - m - 1;
            viewPager3.setCurrentItem(currentPosition);
        }
    }
    
    效果图
    viewPager轮播图.jpeg

    相关文章

      网友评论

        本文标题:用ViewPager实现轮播图:图片无限轮播+动态切换+小圆点切

        本文链接:https://www.haomeiwen.com/subject/pehvyktx.html