详情

首页手游攻略 Android使用ViewPager2实现方式简单的轮播图的代码示例实用指南

Android使用ViewPager2实现方式简单的轮播图的代码示例实用指南

佚名 2026-09-14 17:50:01

平时做技术实践时,很多问题不是概念不会,而是细节没串起来。拿“Android采用ViewPager2实现方法简单的轮播图的代码示例”来说,它看着像小点,放到项目里常会牵出环境、配置、兼容性和维护成本。下面按实际采用顺序,把思路、关键写法和容易踩坑的地方讲清楚,便于大家直接对照操作。

目录
  • 一、轮播图的轻松介绍
  • 二、轮播图的实现步骤
    • 1.绘制轮播图页面
    • 2.设置ViewPager2的子布局
    • 3.编写ViewPager2的适配器
    • 4.编写Carousel类具体实现轮播图
    • 5.实现自动轮播
    • 6.触摸时停止自动轮播
  • 三、完整代码

    一、轮播图的轻松介绍

    轮播图落到代码里,(Carousel)是一种在有限空间内循环展示多个内容项的UI组件,用户能够借助滑动或自动播放的方式浏览不同的内容,在有限的空间中展示更多的内容。

    从实现思路看,实现轮播图主要有两种方式,首尾添加法和取余法,这里主要讲解首尾添加法的实现。

    二、轮播图的实现步骤

    1.绘制轮播图页面

    结合项目来看,添加一个ViewPager2作为轮播图的容器,同时添加LinearLayout放置指示图标

    <?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:id="@+id/main"
        android:layout_
        android:layout_
        tools:context=".MainActivity">

        <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/viewpager2"
            android:layout_
            android:layout_ >
        </androidx.viewpager2.widget.ViewPager2>
    <LinearLayout
        android:id="@+id/botttom_viewpager2"
        android:layout_
        android:layout_
        android:orientation="horizontal"
        android:layout_marginBottom="100dp"
        app:layout_constraintBottom_toBottomOf="@+id/viewpager2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="@+id/viewpager2"
       >
    </LinearLayout>

    </androidx.constraintlayout.widget.ConstraintLayout>

    2.设置ViewPager2的子布局

    新建xml文件,绘制ViewPager2的子布局

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_
        android:layout_>

        <ImageView
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/image"
            android:layout_
            android:layout_
            android:scaleType="centerCrop"/>
    </androidx.constraintlayout.widget.ConstraintLayout>

    3.编写ViewPager2的适配器

    落到代码里,因为ViewPager2实现基于RecyclerView,所以这里直接继承RecyclerView.Adapter

    这里我们采用Glide来加载图片。

    Glide 是一个专注于平滑滚动的 Android 图片加载库。

    优点:

    1.采用轻松,并且兼容多种图片格式,既能够拿到网络资源又能够拿到本地资源,不用处理网络请求、缓存、内存管理、图片解码等复杂逻辑;

    2.性能优秀:自动管理 Bitmap 内存,防止内存溢出,能够自动根据ImageView调整图片大小,节省内存。

    public class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageViewHolder> {
        private List<Integer> images;
        private Context context;
        public ImageAdapter(List<Integer> images){
            this.images=images;
        }
        public int getItemCount(){
            if(images!=null){
                return images.size();
            }
            return 0;
        }
        public ImageViewHolder onCreateViewHolder(ViewGroup parent,int viewType){
            context=parent.getContext();
            View view= LayoutInflater.from(context).inflate(R.layout.layout,parent,false);
            return new ImageViewHolder(view);
        }
        public void onBindViewHolder(ImageViewHolder holder,int position){
            Glide.with(context).load(images.get(position)).into(holder.imageView);
        }
        public static class ImageViewHolder extends RecyclerView.ViewHolder{
            ImageView imageView;
            public ImageViewHolder(View view){
                super(view);
                imageView=view.findViewById(R.id.image);
            }
        }

    4.编写Carousel类具体实现轮播图

    public class Carousel {
        private Context mContext;
        private LinearLayout dotLinearLayout;
        private List<ImageView> mImageList=new ArrayList<>();//标志点集合
        private List<Integer> originalImages=new ArrayList<>();//轮播图图片资源id集合
        private ViewPager2 viewPager2;
        public Carousel(Context mContext, LinearLayout dotLinearLayout, ViewPager2 viewPager2){
            this.mContext=mContext;
            this.dotLinearLayout=dotLinearLayout;
            this.viewPager2=viewPager2;
        }
        public void initViews(int[] resourse){
            //初始化轮播图图片资源id集合
            for(int id:resourse){
                originalImages.add(id);
              ImageView dotImageView=new ImageView(mContext);//制作标记点的ImageView
              if(originalImages.size()==1){
                  dotImageView.setImageResource(R.drawable.blue_dot);//加载第一张图片的标志
              }else {
                  dotImageView.setImageResource(R.drawable.grey_dot);
              }
               LinearLayout.LayoutParams dotImageLayoutParams=new LinearLayout.LayoutParams(60,60);
              dotImageLayoutParams.setMargins(5,0,5,0);
               //设置 dotImageView的布局参数
              dotImageView.setLayoutParams(dotImageLayoutParams);
              mImageList.add(dotImageView);
                //将视图动态添加到布局容器
              dotLinearLayout.addView(dotImageView);
            }
            //将最后一张图片添加到开头,将第一张图片添加到末尾,可以更好实现无限轮播的视觉效果
            originalImages.add(0,originalImages.get(originalImages.size()-1));
            originalImages.add(originalImages.get(1));
            //设置适配器
            ImageAdapter adapter=new ImageAdapter(originalImages);
            viewPager2.setAdapter(adapter);
            viewPager2.setCurrentItem(1,false);
            //设置ViewPager2的页面更改器,处理标志点和边界情况
            viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
                @Override
                public void onPageSelected(int position){
                    for(int i=0;i<mImageList.size();i++){
                        if(i==position-1){
                            mImageList.get(i).setImageResource(R.drawable.blue_dot);
                        }else{
                            mImageList.get(i).setImageResource(R.drawable.grey_dot);
                        }
                    }
                    //滑动到最后一个元素时跳转到第一个元素,滑动到第一个元素时跳转到最后一个元素
                    if(position==originalImages.size()-1){
                        viewPager2.setCurrentItem(1,false);
                    } else if (position==0) {
                        viewPager2.setCurrentItem(originalImages.size()-2,false);
                    }
                }
            });
        }
    }

    在这里轻松解释一下取余法的实现原理

    取余法实现

    设置一个很大的数,借助取余运算拿到真实位置,以实现无限循环的效果

            真实数据: [A, B, C] (3个元素)
            虚拟位置: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ... (无限)
            通过取余: position % 3 = 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, ...
            对应数据: A, B, C, A, B, C, A, B, C, A, ...

    公式: 真实位置 = 虚拟位置 % 图片数量

    落到代码里,开始时从中间位置开始,保证有足够的空间向左滑动,同时且避免在边界处出现问题

    优点:实现轻松,不需修改数据源

    缺点:虽然虚拟位置很大,但RecyclerView会回收视图

    5.实现自动轮播

    理解这一步时,采用Handler实现自动轮播效果,在初始化Carousel时同时注册Handler

        private android.os.Handler handler;
        //设置是否自动播放
        private boolean AUTO_SCROLL=false;
        public Carousel(Context mContext, LinearLayout dotLinearLayout, ViewPager2 viewPager2){
            this.mContext=mContext;
            this.dotLinearLayout=dotLinearLayout;
            this.viewPager2=viewPager2;
            handler=new Handler(Looper.getMainLooper());
        }

    在Carousel中编写控制Handler的方法

     //开启自动轮播
    public void startAutoScrool(){
            handler.removeCallbacks(autoScrollRunnable);//移除之前的回调,防止多次启用
            handler.postDelayed(autoScrollRunnable,Banner_Time);
            AUTO_SCROLL=true;
        }
    //在Runnable中处理自动滚动
        private final Runnable autoScrollRunnable=new Runnable() {
            @Override
            public void run() {
                int current=viewPager2.getCurrentItem();
                if(current==originalImages.size()-2){
                    viewPager2.setCurrentItem(1,false);
                } else{
                    viewPager2.setCurrentItem(current+1);
                }
               handler.postDelayed(this,Banner_Time);
            }
        };
        public void stopAutoScrool(){
            handler.removeCallbacks(autoScrollRunnable);
            AUTO_SCROLL=false;
        }

    6.触摸时停止自动轮播

    从实现思路看,开启自动轮播后,用户就无法借助滑动参看想要的页面,所以我们还应实现触摸时停止自动轮播功能。

    能够借助Viewpager2的滑动行为来实现触摸时停止自动轮播。

    ViewPager2中定义了三种滚动状态:

    三种滚动状态常量
    // 在 ViewPager2 类中定义的常量
    public static final int SCROLL_STATE_IDLE = 0; // 空闲状态,当前没有滚动操作,页面完全静止
    public static final int SCROLL_STATE_DRAGGING = 1; // 拖动状态, 用户正在用手指拖动页面
    public static final int SCROLL_STATE_SETTLING = 2; // 自动滑动状态,页面正在自动滑动到目标位置

    我们借助对三种状态进行分别处理来实现想要的效果。

     viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
                @Override
                public void onPageSelected(int position){
                    for(int i=0;i<mImageList.size();i++){
                        if(i==position-1){
                            mImageList.get(i).setImageResource(R.drawable.blue_dot);
                        }else{
                            mImageList.get(i).setImageResource(R.drawable.grey_dot);
                        }
                    }
                    if(position==originalImages.size()-1){
                        viewPager2.setCurrentItem(1,false);
                    } else if (position==0) {
                        viewPager2.setCurrentItem(originalImages.size()-2,false);
                    }
                }

                @Override
                public void onPageScrollStateChanged(int state) {
                    super.onPageScrollStateChanged(state);
                    if(state==ViewPager2.SCROLL_STATE_DRAGGING){
                        handler.removeCallbacks(autoScrollRunnable);//在拖动时停止自动滚动
                    }
                    //在页面静止时
                    else if (state==ViewPager2.SCROLL_STATE_IDLE&&AUTO_SCROLL) {
                        handler.removeCallbacks(autoScrollRunnable);
                        handler.postDelayed(autoScrollRunnable,Banner_Time);
                    }
                }
            });

    到这里我们就实现了轻松轮播图的全部功能。

    三、完整代码

    下面是实现轮播图的完整代码,以作参考。

    public class Carousel {
        private Context mContext;
        private LinearLayout dotLinearLayout;
        private List<ImageView> mImageList=new ArrayList<>();
        private List<Integer> originalImages=new ArrayList<>();
        private ViewPager2 viewPager2;
        private long Banner_Time=1000;
        private android.os.Handler handler;
        private boolean AUTO_SCROLL=false;
        public Carousel(Context mContext, LinearLayout dotLinearLayout, ViewPager2 viewPager2){
            this.mContext=mContext;
            this.dotLinearLayout=dotLinearLayout;
            this.viewPager2=viewPager2;
            handler=new Handler(Looper.getMainLooper());
        }
        public void initViews(int[] resourse){
            for(int id:resourse){
                originalImages.add(id);
              ImageView dotImageView=new ImageView(mContext);
              if(originalImages.size()==1){
                  dotImageView.setImageResource(R.drawable.blue_dot);
              }else {
                  dotImageView.setImageResource(R.drawable.grey_dot);
              }
              LinearLayout.LayoutParams dotImageLayoutParams=new LinearLayout.LayoutParams(60,60);
              dotImageLayoutParams.setMargins(5,0,5,0);
              dotImageView.setLayoutParams(dotImageLayoutParams);
              mImageList.add(dotImageView);
              dotLinearLayout.addView(dotImageView);
            }
            originalImages.add(0,originalImages.get(originalImages.size()-1));
            originalImages.add(originalImages.get(1));
            ImageAdapter adapter=new ImageAdapter(originalImages);
            viewPager2.setAdapter(adapter);
            viewPager2.setCurrentItem(1,false);
            viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
                @Override
                public void onPageSelected(int position){
                    for(int i=0;i<mImageList.size();i++){
                        if(i==position-1){
                            mImageList.get(i).setImageResource(R.drawable.blue_dot);
                        }else{
                            mImageList.get(i).setImageResource(R.drawable.grey_dot);
                        }
                    }
                    if(position==originalImages.size()-1){
                        viewPager2.setCurrentItem(1,false);
                    } else if (position==0) {
                        viewPager2.setCurrentItem(originalImages.size()-2,false);
                    }
                }

                @Override
                public void onPageScrollStateChanged(int state) {
                    super.onPageScrollStateChanged(state);
                    if(state==ViewPager2.SCROLL_STATE_DRAGGING){
                        handler.removeCallbacks(autoScrollRunnable);
                    }
                    else if (state==ViewPager2.SCROLL_STATE_IDLE&&AUTO_SCROLL) {
                        handler.removeCallbacks(autoScrollRunnable);
                        handler.postDelayed(autoScrollRunnable,Banner_Time);
                    }
                }
            });
        }
        public void startAutoScrool(){
            handler.removeCallbacks(autoScrollRunnable);
            handler.postDelayed(autoScrollRunnable,Banner_Time);
            AUTO_SCROLL=true;
        }
        private final Runnable autoScrollRunnable=new Runnable() {
            @Override
            public void run() {
                int current=viewPager2.getCurrentItem();
                if(current==originalImages.size()-2){
                    viewPager2.setCurrentItem(1,false);
                } else{
                    viewPager2.setCurrentItem(current+1);
                }
               handler.postDelayed(this,Banner_Time);
            }
        };
        public void stopAutoScrool(){
            handler.removeCallbacks(autoScrollRunnable);
            AUTO_SCROLL=false;
        }
    }
    public class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageViewHolder> {
        private List<Integer> images;
        private Context context;
        public ImageAdapter(List<Integer> images){
            this.images=images;
        }
        public int getItemCount(){
            if(images!=null){
                return images.size();
            }
            return 0;
        }
        public ImageViewHolder onCreateViewHolder(ViewGroup parent,int viewType){
            context=parent.getContext();
            View view= LayoutInflater.from(context).inflate(R.layout.layout,parent,false);
            return new ImageViewHolder(view);
        }
        public void onBindViewHolder(ImageViewHolder holder,int position){
            Glide.with(context).load(images.get(position)).into(holder.imageView);
        }
        public static class ImageViewHolder extends RecyclerView.ViewHolder{
            ImageView imageView;
            public ImageViewHolder(View view){
                super(view);
                imageView=view.findViewById(R.id.image);
            }
        }
    }

    最后效果展示如下所示

    从实现思路看,以上就是Android采用ViewPager2实现轻松的轮播图的示例代码的详细内容,更多关于Android ViewPager2轮播图的资料请关注脚本之家其它相关文章!

    您可能感兴趣的文章:

    • Android Viewpager2实现无限轮播图效果
    • Android实现自动变换大小的组件ViewPager2
    • Android ViewPager2 + Fragment 联动效果的实现思路
    • Android ViewPager2 采用及自定义指示器视图实现
    • Android如何采用ViewPager2实现页面滑动切换效果

    相关资讯
    点击查看更多
    游戏推荐
    推荐专题
    热门阅读
    推荐下载