【Android】使用ViewPager2实现轮播图效果,手动/自动轮播图
一、轮播图的制作
1、添加Gilde依赖
这里使用Gilde进行加载图片:Glide
implementation 'com.github.bumptech.glide:glide:4.16.0'
使用Gilde可以加载网络图片还可以提高图片加载性能。
2、制作轮播图布局页面
接下来新建一个子布局item_image,加载viewPage2的子布局。
ViewPage2就是使用recyclerView实现的,所以这里使用方法其实类似。
3、制作ViewPage2的适配器
这里直接继承RecyclerView.Adapter即可,代码很简单不必多说。
class ImageAdapter extends RecyclerView.Adapter { private Context context; private List images; public ImageAdapter(List 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 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; iinitViews的参数是保存加载图片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、效果展示及完整代码如下:
代码可以直接使用,只需要重新设置几个布局文件即可:
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 mDotViewList = new ArrayList();//点视图集合 每个ImageView表示一个点 private Handler autoScrollHandler; //控制自动轮播的线程 private List 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
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理!
部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!
图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!