文章目录
- 1. build.gradle添加依赖:
- 2. AndroidManifest.xml中添加网络访问权限
- 3. 编写 布局文件
- 4. 编写Banner适配器
- 5. 自定义Banner视图
- 6. 定义圆点指示器的drawable资源
- 7. 在需要使用轮播图中的Activity中使用
- 8. 运行效果图
- 9. 视频教程
在Android项目程序设计中,首页轮播图是个很常见的功能,在之前的文章中,教了大家如何使用第三方库来快速实现轮播图(教程地址在文章末尾给出),今天教大家手把手来撸一个轮播图
1. build.gradle添加依赖:
图片显示,采用Glide来加载网络图片
implementation 'com.github.bumptech.glide:glide:4.12.0'
2. AndroidManifest.xml中添加网络访问权限
<uses-permission android:name="android.permission.INTERNET" />
3. 编写 布局文件
activity_banner.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="200dp"><androidx.viewpager2.widget.ViewPager2android:id="@+id/viewPager"android:layout_width="match_parent"android:layout_height="match_parent" /><LinearLayoutandroid:id="@+id/indicator"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_centerHorizontal="true"android:layout_marginBottom="10dp"android:orientation="horizontal" /></RelativeLayout>
4. 编写Banner适配器
BannerAdapter.java
public class BannerAdapter extends RecyclerView.Adapter<BannerAdapter.BannerViewHolder> {private List<String> imageUrls;private Context context;public BannerAdapter(Context context, List<String> imageUrls) {this.context = context;this.imageUrls = imageUrls;}@NonNull@Overridepublic BannerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {ImageView imageView = new ImageView(context);imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT));imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);return new BannerViewHolder(imageView);}@Overridepublic void onBindViewHolder(@NonNull BannerViewHolder holder, int position) {// 使用实际位置加载图片int realPosition = position % imageUrls.size();// 这里使用Glide加载图片,需要添加Glide依赖Glide.with(context).load(imageUrls.get(realPosition)).into(holder.imageView);holder.imageView.setOnClickListener(v -> {// 处理图片点击事件if (onItemClickListener != null) {onItemClickListener.onItemClick(realPosition);}});}@Overridepublic int getItemCount() {// 返回一个很大的数,实现无限循环return Integer.MAX_VALUE;}static class BannerViewHolder extends RecyclerView.ViewHolder {ImageView imageView;public BannerViewHolder(@NonNull View itemView) {super(itemView);imageView = (ImageView) itemView;}}// 点击事件接口public interface OnItemClickListener {void onItemClick(int position);}private OnItemClickListener onItemClickListener;public void setOnItemClickListener(OnItemClickListener listener) {this.onItemClickListener = listener;}
}
这里注意:在方法onBindViewHolder
中,Glide加载图片,需要添加Glide依赖
5. 自定义Banner视图
BannerView.java
public class BannerView extends RelativeLayout {private ViewPager2 viewPager;private LinearLayout indicator;private List<ImageView> indicatorDots;private Handler handler;private static final int SCROLL_TIME = 3000; // 自动滚动间隔private boolean isAutoScroll = true;public BannerView(Context context) {super(context);init(context);}public BannerView(Context context, AttributeSet attrs) {super(context, attrs);init(context);}private void init(Context context) {// 加载布局LayoutInflater.from(context).inflate(R.layout.activity_banner, this, true);viewPager = findViewById(R.id.viewPager);indicator = findViewById(R.id.indicator);indicatorDots = new ArrayList<>();handler = new Handler(Looper.getMainLooper());}public void setImages(List<String> imageUrls) {// 设置适配器BannerAdapter adapter = new BannerAdapter(getContext(), imageUrls);viewPager.setAdapter(adapter);// 设置初始位置到中间viewPager.setCurrentItem(Integer.MAX_VALUE / 2, false);// 创建指示器createIndicators(imageUrls.size());// 设置页面切换监听viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {@Overridepublic void onPageSelected(int position) {updateIndicator(position % imageUrls.size());}});// 开始自动滚动startAutoScroll();}private void createIndicators(int count) {indicator.removeAllViews();indicatorDots.clear();for (int i = 0; i < count; i++) {ImageView dot = new ImageView(getContext());LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(dpToPx(8), dpToPx(8));params.setMargins(dpToPx(4), 0, dpToPx(4), 0);dot.setLayoutParams(params);dot.setImageResource(R.drawable.dot_normal);indicator.addView(dot);indicatorDots.add(dot);}// 设置第一个点为选中状态if (!indicatorDots.isEmpty()) {indicatorDots.get(0).setImageResource(R.drawable.dot_selected);}}private void updateIndicator(int position) {for (int i = 0; i < indicatorDots.size(); i++) {indicatorDots.get(i).setImageResource(i == position ? R.drawable.dot_selected : R.drawable.dot_normal);}}private void startAutoScroll() {handler.postDelayed(new Runnable() {@Overridepublic void run() {if (isAutoScroll && viewPager != null) {viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);handler.postDelayed(this, SCROLL_TIME);}}}, SCROLL_TIME);}public void stopAutoScroll() {isAutoScroll = false;handler.removeCallbacksAndMessages(null);}private int dpToPx(int dp) {return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());}@Overrideprotected void onDetachedFromWindow() {super.onDetachedFromWindow();stopAutoScroll();}
}
6. 定义圆点指示器的drawable资源
- dot_normal.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="oval"><solid android:color="#80FFFFFF" /><sizeandroid:width="8dp"android:height="8dp" />
</shape>
- dot_selected.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="oval"><solid android:color="#FFFFFF" /><sizeandroid:width="8dp"android:height="8dp" />
</shape>
这里注意:dot_normal.xml和dot_selected.xml创建在res
下的drawable
中,而不是res
下的layout
中
7. 在需要使用轮播图中的Activity中使用
- MainActivity.java
public class MainActivity extends AppCompatActivity {private BannerView bannerView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);bannerView = findViewById(R.id.banner_view);// 准备图片URL列表List<String> imageUrls = new ArrayList<>();imageUrls.add("https://img0.baidu.com/it/u=2673431480,3550145287&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=211");imageUrls.add("https://img1.baidu.com/it/u=1588549273,1647024151&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=312");imageUrls.add("https://img2.baidu.com/it/u=3920432635,2105461872&fm=253&fmt=auto&app=138&f=JPEG?w=1600&h=500");imageUrls.add("https://img1.baidu.com/it/u=921161528,741350508&fm=253&fmt=auto&app=138&f=PNG?w=658&h=380");imageUrls.add("https://img2.baidu.com/it/u=611817443,624986336&fm=253&fmt=auto&app=138&f=JPEG?w=1280&h=407");// 设置图片bannerView.setImages(imageUrls);}@Overrideprotected void onDestroy() {super.onDestroy();if (bannerView != null) {bannerView.stopAutoScroll();}}
}
这里注意:一定要在Activity
生命周期的onDestroy()
中调用 bannerView.stopAutoScroll()
方法
- activity_main.xml
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="200dp"><com.app.skill.sharing.views.BannerViewandroid:id="@+id/banner_view"android:layout_width="match_parent"android:layout_height="wrap_content" /></androidx.appcompat.widget.LinearLayoutCompat>
com.app.skill.sharing.views.BannerView
:这里自定义控件的使用为:包名+类名。具体根据自己自定义控件存放的位置而定,在编辑器中输入Ban…,跟使用系统自带控件一样,编辑器会智能提示
8. 运行效果图
9. 视频教程
- Androidstudio轮播图Banner实现 :https://www.bilibili.com/video/BV18B4y1R7gy/?vd_source=984bb03f768809c7d33f20179343d8c8