【Android】使用ViewPager2实现轮播图效果,手动/自动轮播图

这篇具有很好参考价值的文章主要介绍了【Android】使用ViewPager2实现轮播图效果,手动/自动轮播图。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、轮播图的制作

1、添加Gilde依赖

这里使用Gilde进行加载图片:Glide

implementation 'com.github.bumptech.glide:glide:4.16.0'

使用Gilde可以加载网络图片还可以提高图片加载性能。

2、制作轮播图布局页面

<?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="#DAF3FE"
    tools:context=".MainActivity"
    tools:ignore="HardcodedText">


    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewPager2"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <LinearLayout
        android:id="@+id/index_dot"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintBottom_toBottomOf="@+id/viewPager2"
        app:layout_constraintEnd_toEndOf="@+id/viewPager2"
        app:layout_constraintStart_toStartOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

接下来新建一个子布局item_image,加载viewPage2的子布局。

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

    <ImageView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"/>

</androidx.constraintlayout.widget.ConstraintLayout>

ViewPage2就是使用recyclerView实现的,所以这里使用方法其实类似。

3、制作ViewPage2的适配器

这里直接继承RecyclerView.Adapter即可,代码很简单不必多说。

class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageViewHolder> {

    private Context context;
    private List<Integer> images;

    public ImageAdapter(List<Integer> images) {
        this.images = images;
    }

    @NonNull
    @Override
    public ImageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        context = parent.getContext();
        View view = LayoutInflater.from(context).inflate(R.layout.item_image, parent, false);
        return new ImageViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ImageViewHolder holder, int position) {

        //使用Glide加载可以优化加载流程,Glide使用异步操作
        Glide.with(context).load(images.get(position)).into(holder.imageView);
//        holder.imageView.setImageResource(images.get(position));
    }

    @Override
    public int getItemCount() {
        return images != null ? images.size() : 0;
    }

    public static class ImageViewHolder extends RecyclerView.ViewHolder {
        ImageView imageView;

        public ImageViewHolder(@NonNull View itemView) {
            super(itemView);
            imageView = itemView.findViewById(R.id.imageView);
        }
    }
}

4、实现轮播效果

创建一个Carousel类,管理实现轮播图的方法。

private Context mContext;   //全局的Context用于加载图片
private LinearLayout dotLinearLayout;   //用于加载标志点的LinearLayout
private List<ImageView> mDotViewList = new ArrayList<>();//点视图集合 每个ImageView表示一个点
private  long AUTO_SCROLL_INTERVAL = 1_500; // 设置自动滚动的间隔时间,单位为毫秒

public Carousel(Context mContext, LinearLayout dotLinearLayout, ViewPager2 viewPager2) {
    this.mContext = mContext;
    this.dotLinearLayout = dotLinearLayout;
    this.viewPager2 = viewPager2;
}

public void initViews(int[] resource) {

    //加载初始化绑定轮播图
    for (int id : resource) {
        originalImages.add(id);

        //制作标志点的ImageView,并且初始化加载第一张图片标志点
        ImageView dotImageView = new ImageView(mContext);
        if (originalImages.size() == 1) {
            dotImageView.setImageResource(R.drawable.red_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);

        //保存标志点便于后续动态修改
        mDotViewList.add(dotImageView);

        //将标志点的视图绑定在Layout中
        dotLinearLayout.addView(dotImageView);
    }

    originalImages.add(0, originalImages.get(originalImages.size() - 1));  //将originalImages的最后一张照片插入到开头
    originalImages.add(originalImages.get(1));  //将originalImages的第2张照片插入到结尾

    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 < mDotViewList.size(); i++) {
                //由于在第一张图片前添加一张过渡图,因此position比mDotViewList对于的标志点多一位
                if (i == position - 1) {
                    mDotViewList.get(i).setImageResource(R.drawable.red_dot);
                } else {
                    mDotViewList.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);
            }
        }
    });

}

initViews的参数是保存加载图片id的数组,类似于这样:

int[] id = {R.drawable.sys, R.drawable.sys1, R.drawable.sys2, R.drawable.sys3};

5、实现自动轮播

这里使用handler实现一个自动轮播的效果,在实现构造方法的同时实现注册Handler
设置一个全局的变量,用来判断是否设置了自动播放

private boolean AUTO_SCROLL = false; //是否设置自动播放

private Handler autoScrollHandler;  //控制自动轮播的线程

public Carousel(Context mContext, LinearLayout dotLinearLayout, ViewPager2 viewPager2) {
this.mContext = mContext;
this.dotLinearLayout = dotLinearLayout;
this.viewPager2 = viewPager2;

autoScrollHandler = new Handler(Looper.getMainLooper());
}

在Carousel类中加入以下几个方法用于管理handler

/**
     * 启动自动滚动
     */
public void startAutoScroll() {
    autoScrollHandler.removeCallbacks(autoScrollRunnable); // 移除之前的回调,防止多次启动的情况
    autoScrollHandler.postDelayed(autoScrollRunnable, AUTO_SCROLL_INTERVAL);
    AUTO_SCROLL = true;
}

/**
     * 停止自动滚动
     */
public void stopAutoScroll() {
    autoScrollHandler.removeCallbacks(autoScrollRunnable);
    AUTO_SCROLL = false;
}

// 定义自动滚动的 Runnable
private final Runnable autoScrollRunnable = new Runnable() {
    @Override
    public void run() {
        // 在这里处理自动滚动逻辑
        int currentItem = viewPager2.getCurrentItem();

        //当自动轮播到最后一张图片时,又从头开始轮播
        if (currentItem == originalImages.size() - 2) {
            viewPager2.setCurrentItem(1);
        } else {
            viewPager2.setCurrentItem(currentItem + 1);
        }

        // 重新调度下一次自动滚动
        autoScrollHandler.postDelayed(this, AUTO_SCROLL_INTERVAL);
    }
};

6、触摸暂停滚动

此时出现一个新的问题,在我们手动滑动轮播图时,handler依然控制图片移动,导致用户无法拖动的自己想看的一页。这个解决方法很简单,在ViewPage2的滑动监听事件中监听滑动行为即可。

@Override
public void onPageScrollStateChanged(int state) {
    super.onPageScrollStateChanged(state);

     // 当滑动开始时停止自动滚动
     if (state == ViewPager2.SCROLL_STATE_DRAGGING) {
         autoScrollHandler.removeCallbacks(autoScrollRunnable);
     }
     // 当滑动结束时重新启动自动滚动
     else if (state == ViewPager2.SCROLL_STATE_IDLE && AUTO_SCROLL) {
         autoScrollHandler.removeCallbacks(autoScrollRunnable); // 移除之前的回调,防止多次启动的情况
         autoScrollHandler.postDelayed(autoScrollRunnable, AUTO_SCROLL_INTERVAL);
     }
 }

7、效果展示及完整代码如下:

viewpager2 轮播,Android,Android,java,ViewPager2,轮播图

代码可以直接使用,只需要重新设置几个布局文件即可:文章来源地址https://www.toymoban.com/news/detail-775804.html

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager2.widget.ViewPager2;

import com.bumptech.glide.Glide;

import java.util.ArrayList;
import java.util.List;


public class Carousel {

    private Context mContext;   //全局的Context用于加载图片
    private LinearLayout dotLinearLayout;   //用于加载标志点的LinearLayout
    private List<ImageView> mDotViewList = new ArrayList<>();//点视图集合 每个ImageView表示一个点

    private Handler autoScrollHandler;  //控制自动轮播的线程

    private List<Integer> originalImages = new ArrayList<>();   //存放这需要轮播的图片

    private ViewPager2 viewPager2;

    private long AUTO_SCROLL_INTERVAL = 1_500; // 设置自动滚动的间隔时间,单位为毫秒

	private boolean AUTO_SCROLL = false;    //是否设置自动播放


    /**
     * @param AUTO_SCROLL_INTERVAL 设置轮播图自动滚动时间
     */
    public void setAUTO_SCROLL_INTERVAL(long AUTO_SCROLL_INTERVAL) {
        this.AUTO_SCROLL_INTERVAL = AUTO_SCROLL_INTERVAL;
    }

    public Carousel(Context mContext, LinearLayout dotLinearLayout, ViewPager2 viewPager2) {
        this.mContext = mContext;
        this.dotLinearLayout = dotLinearLayout;
        this.viewPager2 = viewPager2;

        autoScrollHandler = new Handler(Looper.getMainLooper());
    }

    /**
     * 用于启动轮播图效果
     *
     * @param resource 图片的资源ID
     */
    public void initViews(int[] resource) {

        //加载初始化绑定轮播图
        for (int id : resource) {
            originalImages.add(id);

            //制作标志点的ImageView,并且初始化加载第一张图片标志点
            ImageView dotImageView = new ImageView(mContext);
            if (originalImages.size() == 1) {
                dotImageView.setImageResource(R.drawable.red_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);

            //保存标志点便于后续动态修改
            mDotViewList.add(dotImageView);

            //将标志点的视图绑定在Layout中
            dotLinearLayout.addView(dotImageView);
        }

        originalImages.add(0, originalImages.get(originalImages.size() - 1));  //将originalImages的最后一张照片插入到开头
        originalImages.add(originalImages.get(1));  //将originalImages的第2张照片插入到结尾

        ImageAdapter adapter = new ImageAdapter(originalImages);
        viewPager2.setAdapter(adapter);

        // 设置当前项为数据集的第一个元素,使其显示为轮播图的开始
        viewPager2.setCurrentItem(1, false);

        // 添加页面更改监听器,以实现循环滚动
        viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {

            @Override
            public void onPageScrollStateChanged(int state) {
                super.onPageScrollStateChanged(state);

            // 当滑动开始时停止自动滚动
            if (state == ViewPager2.SCROLL_STATE_DRAGGING) {
                autoScrollHandler.removeCallbacks(autoScrollRunnable);
            }
            // 当滑动结束时重新启动自动滚动
            else if (state == ViewPager2.SCROLL_STATE_IDLE && AUTO_SCROLL) {
                autoScrollHandler.removeCallbacks(autoScrollRunnable); // 移除之前的回调,防止多次启动的情况
                autoScrollHandler.postDelayed(autoScrollRunnable, AUTO_SCROLL_INTERVAL);
            }
        }

            @Override
            public void onPageSelected(int position) {

                //动态设置图片的下标点位
                for (int i = 0; i < mDotViewList.size(); i++) {
                    //由于在第一张图片前添加一张过渡图,因此position比mDotViewList对于的标志点多一位
                    if (i == position - 1) {
                        mDotViewList.get(i).setImageResource(R.drawable.red_dot);
                    } else {
                        mDotViewList.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);
                }
            }
        });

    }

    /**
     * 启动自动滚动
     */
    public void startAutoScroll() {
        autoScrollHandler.removeCallbacks(autoScrollRunnable); // 移除之前的回调,防止多次启动的情况
        autoScrollHandler.postDelayed(autoScrollRunnable, AUTO_SCROLL_INTERVAL);
        AUTO_SCROLL = true;
    }

    /**
     * 停止自动滚动
     */
    public void stopAutoScroll() {
        autoScrollHandler.removeCallbacks(autoScrollRunnable);
        AUTO_SCROLL = false;
    }

    // 定义自动滚动的 Runnable
    private final Runnable autoScrollRunnable = new Runnable() {
        @Override
        public void run() {
            // 在这里处理自动滚动逻辑
            int currentItem = viewPager2.getCurrentItem();

            //当自动轮播到最后一张图片时,又从头开始轮播
            if (currentItem == originalImages.size() - 2) {
                viewPager2.setCurrentItem(1);
            } else {
                viewPager2.setCurrentItem(currentItem + 1);
            }

            // 重新调度下一次自动滚动
            autoScrollHandler.postDelayed(this, AUTO_SCROLL_INTERVAL);
        }
    };
}

class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageViewHolder> {

    private Context context;
    private List<Integer> images;

    public ImageAdapter(List<Integer> images) {
        this.images = images;
    }

    @NonNull
    @Override
    public ImageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        context = parent.getContext();
        View view = LayoutInflater.from(context).inflate(R.layout.item_image, parent, false);
        return new ImageViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ImageViewHolder holder, int position) {

        //使用Glide加载可以优化加载流程,Glide使用异步操作
        Glide.with(context).load(images.get(position)).into(holder.imageView);
//        holder.imageView.setImageResource(images.get(position));
    }

    @Override
    public int getItemCount() {
        return images != null ? images.size() : 0;
    }

    public static class ImageViewHolder extends RecyclerView.ViewHolder {
        ImageView imageView;

        public ImageViewHolder(@NonNull View itemView) {
            super(itemView);
            imageView = itemView.findViewById(R.id.imageView);
        }
    }
}

到了这里,关于【Android】使用ViewPager2实现轮播图效果,手动/自动轮播图的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • android 关于TabLayout联动ViewPager2 实现底部导航栏

    最近在心血来潮想写在app 不过我关于android可以说是0基础 在写底部导航栏的时候去问了大佬才知道TabLayout和ViewPager 花了两天才看懂... 这里只是简单介绍因为我不准备专门做安卓软件所以在学的途中很多地方没有认真记 本篇文章使用的代码是Java 这里官方是有将两个进行联动

    2024年01月25日
    浏览(43)
  • Android:ViewPager2

    ViewPager2内部使用RecyclerView实现,并提供了增强功能 支持水平、垂直方向布局 android:orientation = “vertical” 支持从右到左 android:layoutDirection = “rtl” 禁止滑动 setUserInputEnabled() 可修改Fragment集合 对可修改的Fragment集合进行分页浏览,底层集合更改时调用notifyDatasetChanged来更新页

    2024年02月09日
    浏览(40)
  • Android进阶之路 - ViewPager2 比 ViewPager 强在哪?

    我记得前年(2022)面试的时候有被问到 ViewPager 和 ViewPager2 有什么区别?当时因为之前工作一直在开发售货机相关的项目,使用的技术要求并不高,所以一直没去了解过 ViewPager2~ 去年的时候正好有相关的功能需求,索性直接用 ViewPager2 进行了 Tip :很多人可能比较关注俩者区

    2024年02月20日
    浏览(51)
  • vue实现轮播图效果

    1,实现轮左右按键轮播效果,采用数组下标指定轮播图片,定义一个dindex与index下标相比较。 2,创建轮播的图片的数组 3,实现下方圆点点击轮播图片,采用动态绑定和数组的动态样式实现未点击的白色和点击的黑色 dindex与index相比较两值相不一致就是白色反之为黑色 4,实现

    2024年02月11日
    浏览(46)
  • 【Android基础面试题】ViewPager与ViewPager2的区别

    ViewPager和ViewPager2是Android中用于实现滑动页面切换的控件。它们的主要区别如下: 实现方式 ViewPager2的内部实现是RecyclerView,而ViewPager是通过继承自ViewGroup实现的。因此,ViewPager2的性能更高。 滑动方向 ViewPager2可以实现横向和竖向滑动,而ViewPager只能横向滑动。 Adapter:View

    2024年02月11日
    浏览(45)
  • Android ViewPager2 + Fragment 联动

    本篇主要介绍一下 ViewPager2 + Fragment , 上篇中简单使用了ViewPager2 实现了一个图片的滑动效果, 那图片视图可以滑动, ViewPager2也可以滑动 Fragment 概述 ViewPager2 官方对它的描述就是 以可滑动的格式显示视图或 Fragment 也就说明提供了滑动Fragment的实现 并且还很简单, 下面来看看吧

    2023年04月08日
    浏览(44)
  • js实现左右切换轮播图效果

    实现效果: 自动向右循环播放 鼠标悬停,移出继续播放 点击向右按钮,跳到下一张 点击向左按钮,跳到上一张 保证图片的过渡效果完整呈现后,才能跳到下一张 底部圆点随图片位置切换激活状态 实现思路: 把第一张图片复制到最后一张 当播放到最后一张时,无缝切换到

    2024年01月20日
    浏览(57)
  • uni-app小程序折叠3D轮播图效果实现。

    先来看效果图 实现原理: 通过小程序的触摸事件,来控制图片数组的变化实现动态样式;来改变图片的样式。 贴上轮播组件完整代码 组件使用 如果有自动轮播的需求,可以改造下组件加个定时器处理数组就OK了。

    2024年02月11日
    浏览(45)
  • vue 实现钉钉官网的轮播图下面功能滚动排版CSS效果

    前言 最近在写PC端的业主端时候,发现传统的菜单栏比较丑,也不符合实际应用(功能页面并不多-展示为主) 偶然发现钉钉官网的效果挺有意思的,想着把这个效果复原过来,然后夸夸搜索了一番。 经过一顿的cv打法,加上修修补补把大概的效果整了出来,时间关系最基础

    2024年02月11日
    浏览(56)
  • ViewPager2与TabLayout的简单使用

    ViewPager2与TabLayout的简单使用 MainActivity.java activity_main.xml ViewPagerAdapter.java ShowBigIdBean.java item_img.xml item_icon_layout.xml item_circle_shape.xml

    2024年02月12日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包