本文共 7161 字,大约阅读时间需要 23 分钟。
本篇使用的是基于viewpager2的一个开源banner,性能、生命周期都有保障,就是有一点小的功能需要我们自己去修改。本篇也是作为简易音乐博客系列之一。
在工程build下添加仓库maven:
allprojects { repositories { google() jcenter() maven { url "https://s01.oss.sonatype.org/content/groups/public" } }}
在项目build下添加banner和viewpager2的引用:
implementation 'io.github.youth5201314:banner:2.2.2' implementation "androidx.viewpager2:viewpager2:1.0.0"
public class DataBean implements Serializable { public String imageUrl; public String title; public String url; public DataBean(String imageUrl, String title) { this.imageUrl = imageUrl; this.title = title; } public void setImageUrl(String imageUrl) { this.imageUrl = imageUrl; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public void setTitle(String title) { this.title = title; } public String getImageUrl() { return imageUrl; } public String getTitle() { return title; } public static ListgetTestData() { List list = new ArrayList<>(); list.add(new DataBean("https://dfzximg02.dftoutiao.com/news/20210401/20210401222253_acbd3f414dc150c4cf25d91dcac0cf36_1_mwpm_03201609.jpeg", "标题0" )); list.add(new DataBean("https://dfzximg02.dftoutiao.com/news/20210401/20210401222253_acbd3f414dc150c4cf25d91dcac0cf36_2_mwpm_03201609.jpeg", "标题1" )); list.add(new DataBean("https://dfzximg02.dftoutiao.com/news/20210401/20210401221040_d2957dc25d3878b4fdf0816289cde4fd_1_mwpm_03201609.png", "标题2")); list.add(new DataBean("http://cn.bing.com/th?id=OHR.FooledYa_EN-CN7497696381_1920x1080.jpg", "标题3")); list.add(new DataBean("https://dfzximg02.dftoutiao.com/news/20210401/20210401222006_3a2f89e1dbaa16f8a7f7754e00d8bf77_1_mwpm_03201609.jpeg", "标题4")); return list; }}
修改主界面布局文件:
修改MainActivity.java
,简单使用banner轮播功能:
public class MainActivity extends AppCompatActivity { Banner banner; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initData(); } private void initView() { findViewById(R.id.button).setOnClickListener(v -> { Intent intent = new Intent(this,Main2Activity.class); startActivity(intent); }); banner = findViewById(R.id.banner); } private void initData() { //banner自带图片轮播的适配器 banner.setAdapter(new BannerImageAdapter(DataBean.getTestData()) { @Override public void onBindView(BannerImageHolder holder, DataBean data, int position, int size) { Glide.with(holder.imageView) .load(data.imageUrl) .thumbnail(Glide.with(holder.itemView).load(R.drawable.loading))//加载成功前显示一个loading的加载 //.apply(RequestOptions.bitmapTransform(new RoundedCorners(30))) //设置图片圆角 .into(holder.imageView); //关于glide的引用添加: //implementation 'com.github.bumptech.glide:glide:4.11.0' //annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0' } }).addBannerLifecycleObserver(this)//添加生命周期观察者 .setIntercept(false) //是否要拦截事件 .setBannerRound(10f) //圆角 .setIndicator(new CircleIndicator(this)) //圆形指示器 还支持条形指示器等 .setOnBannerListener(new OnBannerListener() { @Override public void OnBannerClick(Object data, int position) { Toast.makeText(MainActivity.this,"位置"+position+"",Toast.LENGTH_SHORT).show(); } }) ; }}
到这,基本的轮播功能已经实现了,但是很多轮播图可能还需要有标题,即图片+标题,就要自己编写适配器继承BannerAdapter
,首先编写一个banner_title_image.xml
的布局文件(就是一个简单的图片加标题):
第二步,编写TitleHolder
继承ViewHolder:
public class TitleHolder extends RecyclerView.ViewHolder { public ImageView imageView; public TextView textView; public TitleHolder(@NonNull View itemView) { super(itemView); imageView = itemView.findViewById(R.id.bannerImage); textView = itemView.findViewById(R.id.bannerTitle); }}
第三步,编写ImageTitleAdapter
继承banner三方提供的BannerAdapter:
/** * banner轮播图适配器 图片+标题 */public class ImageTitleAdapter extends BannerAdapter{ public ImageTitleAdapter(List datas) { super(datas); } @Override public TitleHolder onCreateHolder(ViewGroup parent, int viewType) { return new TitleHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.banner_title_image,parent,false)); } @Override public void onBindView(TitleHolder holder, DataBean data, int position, int size) { Glide.with(holder.imageView) .load(data.imageUrl) .thumbnail(Glide.with(holder.itemView).load(R.drawable.loading)) .into(holder.imageView); holder.textView.setText(data.title); }}
第四步,修改MainActivity.java
:
private void initData() { banner.setAdapter(new ImageTitleAdapter(DataBean.getTestData())).addBannerLifecycleObserver(this)//添加生命周期观察者 .setIntercept(false) //是否要拦截事件 .setBannerRound(10f) //圆角 .setIndicator(new RectangleIndicator(this)) //线条指示器 .setIndicatorHeight(5) .setIndicatorWidth(6,6) //选中下宽度是否一致 .setIndicatorGravity(IndicatorConfig.Direction.CENTER) .setOnBannerListener(new OnBannerListener() { @Override public void OnBannerClick(Object data, int position) { Toast.makeText(MainActivity.this,"位置"+position+"",Toast.LENGTH_SHORT).show(); } }) ; }
正常情况下使用这个三方轮播图已经结束了,毕竟效果啥的都实现了,但是实际使用中还是发现一些问题,比如在fragment中使用的时候进行fragment切换,再回来就会从头加载轮播,这怎么行,暂时解决办法是在fragmetnt
下(自己选的只能被迫自己解决问题):
//定义一个int保存当前轮播位置 private static int potsition = 0; @Override public void onPause() { super.onPause(); potsition = banner.getViewPager2().getCurrentItem(); //用提供的banner.getCurrentItem()获取不到 } @Override public void onResume() { super.onResume(); if (potsition != 0&&banner !=null){ //从选中位置开始轮播 banner.setStartPosition(potsition); } }
后面发型是因为我在母体Activity中通过开启事务后FragmentTransaction.replace()
方法替换fragment(本质上还是调用了remove造成了移除fragment_main碎片,重新新增fragment_main碎片导致fragment_main反复调用onpause->onStop->…onResume()导致的轮播图重新实例化)
FragmentManager fm = getSupportFragmentManager(); FragmentTransaction transaction = fm.beginTransaction(); //切换布局 transaction.replace(R.id.frame_main,fragment); transaction.commit();
本篇文章到此结束,有问题欢迎批评指正,觉得不错的也请点个赞奥
转载地址:http://epdqi.baihongyu.com/