Android Viewpager2实现无限轮播图效果
<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>Android Viewpager2实现无限轮播图</li><ul class="second_class_ul"><li>🏇先上效果图</li><li>🎍使用步骤</li><ul class="third_class_ul"><li>🏀step1 添加依赖</li><li>🍔step2 自定义RecyclerView.Adapter</li><li>🚗step3 在页面中使用</li><li>关键点分析</li><li>🍟如何自定义Indicator</li><li>🛌内置IndicatorView使用方法介绍,没有提供任何自定义属性</li></ul></ul></ul></div><p>ViewPager2是Android Jetpack组件的一部分,用于实现屏幕间平滑的水平滚动效果。相比其前身ViewPager,ViewPager2在性能上有所提升,且支持RTL(从右到左的布局)和垂直滚动等特性。其用法简洁,可以很容易地与RecyclerView Adapter集成,以展示大量数据集。</p><p class="maodian"></p><h2>Android Viewpager2实现无限轮播图</h2>
<p class="maodian"></p><h3>🏇先上效果图</h3>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202509/2025091911423829.gif" /></p>
<p>这就类似于常用软件首页的广告轮播图,这里只是简单显示了几张图片,当然你还可以自定义更精美的子项布局来实现想要的效果。</p>
<p class="maodian"></p><h3>🎍使用步骤</h3>
<p class="maodian"></p><h4>🏀step1 添加依赖</h4>
<p>首先在app/build.gradle文件中添加依赖:</p>
<div class="jb51code"><pre class="brush:java;">implementation 'androidx.viewpager2:viewpager2:1.0.0'
implementation 'me.relex:circleindicator:2.1.6'</pre></div>
<p class="maodian"></p><h4>🍔step2 自定义RecyclerView.Adapter</h4>
<div class="jb51code"><pre class="brush:java;">package com.example.viewpager2test;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
public class CarouselAdapter extends RecyclerView.Adapter<CarouselAdapter.ViewHolder> {
private final int[] imageResources; // 图片资源数组
public CarouselAdapter(int[] imageResources) {
this.imageResources = imageResources;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_carousel, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.imageView.setImageResource(imageResources);
}
@Override
public int getItemCount() {
return imageResources.length;
}
static class ViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
ViewHolder(View view) {
super(view);
imageView = view.findViewById(R.id.imageView);
}
}
}</pre></div>
<p>其实Viewpager2的底层是基于RecyclerView实现的,所以用法基本上差不多,都是要自定义适配器和子项布局,在适配器中实现布局加载,控件的初始化和数据绑定等操作。</p>
<p class="maodian"></p><h4>🚗step3 在页面中使用</h4>
<div class="jb51code"><pre class="brush:java;">package com.example.viewpager2test;
import android.os.Bundle;
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.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager2.widget.ViewPager2;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private ViewPager2 viewPager;
private LinearLayout indicatorLayout;
private BannerAdapter adapter;
private Handler handler = new Handler(Looper.getMainLooper());
private Runnable autoScrollRunnable;
private int currentPage = 0;
private static final long AUTO_SCROLL_DELAY = 2000; // 3秒轮播间隔
private static final int INITIAL_POSITION = 1000; // 初始位置
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EdgeToEdge.enable(this);
// 初始化视图
viewPager = findViewById(R.id.viewPager);
indicatorLayout = findViewById(R.id.indicatorLayout);
// 创建图片资源列表
List<Integer> images = new ArrayList<>();
images.add(R.drawable.image1);
images.add(R.drawable.image2);
images.add(R.drawable.image3);
images.add(R.drawable.image4);
// 设置适配器
adapter = new BannerAdapter(images);
viewPager.setAdapter(adapter);
// 设置初始位置(实现无限循环)
viewPager.setCurrentItem(INITIAL_POSITION, false);
currentPage = INITIAL_POSITION;
// 添加指示器
setupIndicators(images.size());
// 设置页面变化监听器
viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
currentPage = position;
updateIndicators(position % images.size());
}
});
// 设置自动轮播
autoScrollRunnable = new Runnable() {
@Override
public void run() {
if (currentPage == adapter.getItemCount() - 1) {
currentPage = INITIAL_POSITION;
viewPager.setCurrentItem(currentPage, false);
} else {
viewPager.setCurrentItem(++currentPage, true);
}
handler.postDelayed(this, AUTO_SCROLL_DELAY);
}
};
// 触摸暂停功能
viewPager.setOnTouchListener((v, event) -> {
stopAutoScroll();
return false;
});
}
@Override
protected void onResume() {
super.onResume();
startAutoScroll();
}
@Override
protected void onPause() {
super.onPause();
stopAutoScroll();
}
private void setupIndicators(int count) {
indicatorLayout.removeAllViews();
for (int i = 0; i < count; i++) {
ImageView indicator = new ImageView(this);
indicator.setImageResource(i == 0 ? R.drawable.indicator_active : R.drawable.indicator_inactive);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
dpToPx(8), dpToPx(8)
);
params.setMargins(dpToPx(4), 0, dpToPx(4), 0);
indicator.setLayoutParams(params);
indicatorLayout.addView(indicator);
}
}
private void updateIndicators(int position) {
for (int i = 0; i < indicatorLayout.getChildCount(); i++) {
ImageView indicator = (ImageView) indicatorLayout.getChildAt(i);
indicator.setImageResource(i == position ?
R.drawable.indicator_active : R.drawable.indicator_inactive);
}
}
private void startAutoScroll() {
handler.postDelayed(autoScrollRunnable, AUTO_SCROLL_DELAY);
}
private void stopAutoScroll() {
handler.removeCallbacks(autoScrollRunnable);
}
private int dpToPx(int dp) {
float density = getResources().getDisplayMetrics().density;
return Math.round(dp * density);
}
// 适配器类
static class BannerAdapter extends RecyclerView.Adapter<BannerAdapter.ViewHolder> {
private final List<Integer> images;
public BannerAdapter(List<Integer> images) {
this.images = images;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_banner, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
int realPosition = position % images.size();
holder.imageView.setImageResource(images.get(realPosition));
}
@Override
public int getItemCount() {
return Integer.MAX_VALUE; // 实现无限循环
}
static class ViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
public ViewHolder(@NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.imageView);
}
}
}
}</pre></div>
<p class="maodian"></p><h4>关键点分析</h4>
<h5>无限循环原理</h5>
<div class="jb51code"><pre class="brush:java;">// 自动轮播系统
autoScrollRunnable = new Runnable() {
@Override
public void run() {
if (currentPage == adapter.getItemCount() - 1) {
currentPage = INITIAL_POSITION;
viewPager.setCurrentItem(currentPage, false); // 无动画跳转
} else {
viewPager.setCurrentItem(++currentPage, true); // 平滑滚动
}
handler.postDelayed(this, AUTO_SCROLL_DELAY);
}
};</pre></div>
<div class="jb51code"><pre class="brush:java;">@Override
public int getItemCount() {
return Integer.MAX_VALUE; // 实现无限循环
}</pre></div>
<p>通过设置Integer的最大值(2147483646)达到无限循环效果,同时通过<code>setCurrentItem(INITIAL_POSITION)</code>设定初始位置在索引等于1000的位置确保起始点在中间位置,每次轮播时通过<code>position % images.size()</code>计算实际索引获取真实图片位置。</p>
<p class="maodian"></p><h4>🍟如何自定义Indicator</h4>
<div class="jb51code"><pre class="brush:java;">private void setupIndicators(int count) {
indicatorLayout.removeAllViews();
for (int i = 0; i < count; i++) {
ImageView indicator = new ImageView(this);
indicator.setImageResource(i == 0 ? R.drawable.indicator_active : R.drawable.indicator_inactive);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
dpToPx(8), dpToPx(8)
);
params.setMargins(dpToPx(4), 0, dpToPx(4), 0);
indicator.setLayoutParams(params);
indicatorLayout.addView(indicator);
}
}
private void updateIndicators(int position) {
for (int i = 0; i < indicatorLayout.getChildCount(); i++) {
ImageView indicator = (ImageView) indicatorLayout.getChildAt(i);
indicator.setImageResource(i == position ?
R.drawable.indicator_active : R.drawable.indicator_inactive);
}
}</pre></div>
<p class="maodian"></p><h4>🛌内置IndicatorView使用方法介绍,没有提供任何自定义属性</h4>
<table><thead><tr><th>方法名</th><th>描述</th></tr></thead><tbody><tr><td>setIndicatorRadius(float indicatorRadius)</td><td>设置圆点半径</td></tr><tr><td>setIndicatorSpacing(float indicatorSpacing)</td><td>设置圆点间距</td></tr><tr><td>setIndicatorStyle(@IndicatorStyle int indicatorStyle)</td><td>设置圆点切换动画,内置五种切换动画</td></tr><tr><td>setIndicatorColor(@ColorInt int indicatorColor)</td><td>设置默认的圆点颜色</td></tr><tr><td>setIndicatorSelectorColor(@ColorInt int indicatorSelectorColor)</td><td>设置选中的圆点颜色</td></tr><tr><td>setParams(RelativeLayout.LayoutParams params)</td><td>设置IndicatorView在banner中的位置,默认底部居中,距离底部10dp</td></tr><tr><td>setIndicatorRatio(float indicatorRatio)</td><td>设置indicator比例,拉伸圆为矩形,设置越大,拉伸越长,默认1.0</td></tr><tr><td>setIndicatorSelectedRadius(float indicatorSelectedRadius)</td><td>设置选中的圆角,默认和indicatorRadius值一致,可单独设置选中的点大小</td></tr><tr><td>setIndicatorSelectedRatio(float indicatorSelectedRatio)</td><td>设置选中圆比例,拉伸圆为矩形,控制该比例,默认比例和indicatorRatio一致,默认值1.0</td></tr><tr><td>atorRatio(float indicatorRatio)</td><td>设置indicator比例,拉伸圆为矩形,设置越大,拉伸越长,默认1.0</td></tr><tr><td>setIndicatorSelectedRadius(float indicatorSelectedRadius)</td><td>设置选中的圆角,默认和indicatorRadius值一致,可单独设置选中的点大小</td></tr><tr><td>setIndicatorSelectedRatio(float indicatorSelectedRatio)</td><td>设置选中圆比例,拉伸圆为矩形,控制该比例,默认比例和indicatorRatio一致,默认值1.0</td></tr></tbody></table>
<p>到此这篇关于Android Viewpager2实现无限轮播图效果的文章就介绍到这了,更多相关Android Viewpager2轮播图内容请搜索琼殿技术社区以前的文章或继续浏览下面的相关文章希望大家以后多多支持琼殿技术社区!</p>
<div class="art_xg">
<b>您可能感兴趣的文章:</b><ul><li>android ViewPager实现一个无限轮播图</li><li>Android ViewPager自定义轮播图并解决播放冲突</li><li>Android使用RollViewPager实现轮播图</li><li>Android Viewpager实现无限循环轮播图</li><li>Android使用viewpager实现自动无限轮播图</li><li>Android ViewPager实现轮播图效果</li><li>Android实现基于ViewPager的无限循环自动播放带指示器的轮播图CarouselFigureView控件</li></ul>
</div>
</div>
<!--endmain-->
頁:
[1]