目录
前言
在前面的博客中(XUI 熟练使用之(一) ----------- 将 XUI 引入项目)我们已经学习了如何将 XUI 导入到我们的项目中,由于作者发布的示例项目很多地方对于我这样的新手来说,还不太容易理解,其中很多的控件不能做到开箱即用的效果,需要先熟悉一下示例项目结构等。所以接下来的一系列博文,我将一 一分享我的 XUI 学习之旅,已达到大家看了文章立马就会使用 XUI 的各种强大的控件。今天我们将一起学习 XUI 中强大的 轮播条 的使用。在 XUI 中,作者使用了两种方式来实现,RecyclerView 和 ViewPager 。
1、 RecyclerViewBanner 的使用
顾名思义,RecyclerViewBanner 轮播条作者是通过 RecyclerView 来实现的。
长话短说,我们直接上案例。
示例
在开始之前,我们需要先做一些初始化设置,比如 application 设置和主题设置。在 XUI 熟练使用之(一) ----------- 将 XUI 引入项目 中做了详细介绍,大家可以关注一下。
由于本示例使用的图片是网上的图片,所以需要在清单文件中加入访问网络的权限。
<uses-permission android:name="android.permission.INTERNET"/>
另外 当 API 为28 或 高于 28 时需要在 application 标签内添加 android:usesCleartextTraffic=“true” 才能使用网络,即使用明文 HTTP 等。
在 activity_main.xml 中使用 BannerLayout 来添加 轮播条 控件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
tools:context=".MainActivity">
<!--轮播条控件-->
<com.xuexiang.xui.widget.banner.recycler.BannerLayout
android:id="@+id/bl"
android:layout_width="match_parent"
android:layout_height="200dp"
app:bl_autoPlaying="true"
app:bl_centerScale="1.5"
app:bl_interval="1000"
app:bl_itemSpace="10dp"
app:bl_moveSpeed="1.8" />
</LinearLayout>
这里我们用到了一些 轮播条 的自定义属性,我们后面再做说明。
使用 BannerLayout 和我们使用 RecyclerView 一样,我们也需要创建一个 Adapter 适配器,给 轮播条 设置数据 或者 item 点击事件。
BannerAdapter.java:
public class BannerAdapter extends RecyclerView.Adapter<BannerAdapter.BannerViewHolder>{
private String[] urls;//图片地址
private Context context;
public BannerAdapter(Context context, String[] urls){
this.urls = urls;
this.context = context;
}
@NonNull
@Override
public BannerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.banner_item, parent, false);
return new BannerViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull BannerViewHolder holder, int position) {
ImageView imageView = holder.imageView;
//XUI 的图片加载器
ImageLoader.get().loadImage(imageView, urls[position]);
}
@Override
public int getItemCount() {
return urls.length;
}
class BannerViewHolder extends RecyclerView.ViewHolder{
ImageView imageView;//轮播条的 item 项
public BannerViewHolder(@NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.iv_item);
}
}
}
轮播条的每一项的布局,iv_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="250dp"
android:layout_height="100dp"
app:cardCornerRadius="5dp">
<ImageView
android:id="@+id/iv_item"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" />
</LinearLayout>
接下来我们需要 MainActivity.java 中获取 BannerLayout 控件实例,并为其设置 Adapter。
MainActivity.java:
public class MainActivity extends AppCompatActivity {
private BannerAdapter mAdapter;
private BannerLayout mBl;
public String[] urls = new String[]{//轮播图片地址
"http://photocdn.sohu.com/tvmobilemvms/20150907/144160323071011277.jpg",
"http://photocdn.sohu.com/tvmobilemvms/20150907/144158380433341332.jpg",
"http://photocdn.sohu.com/tvmobilemvms/20150907/144160286644953923.jpg",
"http://photocdn.sohu.com/tvmobilemvms/20150902/144115156939164801.jpg",
"http://photocdn.sohu.com/tvmobilemvms/20150907/144159406950245847.jpg",
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBl = findViewById(R.id.bl);
mAdapter = new BannerAdapter(this,urls);
mBl.setAdapter(mAdapter);
}
}
到此为止,我们 轮播条 控件就可以在界面上显示了:
常用属性
(1)、app:bl_centerScale 图片缩放系数,默认值是1.2。
(2)、app:bl_autoPlaying 是否自动滚动,默认为 true。
(3)、app:bl_orientation 轮播的方向,有垂直和水平两种方式。
(4)、app:bl_indicatorSelectedSrc 指示器被选中时,可以为其设置指定的资源文件,bl_indicatorSelectedColor 为其设置选中时的颜色。
更多属性可以参考 作者的源码注释:
<declare-styleable name="BannerLayout">
<!--轮播间隔,单位ms,默认是4000ms-->
<attr format="integer" name="bl_interval"/>
<!--是否显示轮播索引,默认是true-->
<attr format="boolean" name="bl_showIndicator"/>
<!--轮播的方向,默认是horizontal-->
<attr format="enum" name="bl_orientation">
<enum name="horizontal" value="0"/>
<enum name="vertical" value="1"/>
</attr>
<!--是否是自动轮播,默认是true-->
<attr format="boolean" name="bl_autoPlaying"/>
<!--轮播索引选中的效果-->
<attr format="reference" name="bl_indicatorSelectedSrc"/>
<!--轮播索引未选中的效果-->
<attr format="reference" name="bl_indicatorUnselectedSrc"/>
<!--轮播索引的大小,默认5dp-->
<attr format="dimension" name="bl_indicatorSize"/>
<!--轮播索引选中的颜色-->
<attr format="color" name="bl_indicatorSelectedColor"/>
<!--轮播索引未选中的颜色-->
<attr format="color" name="bl_indicatorUnselectedColor"/>
<!--索引器之间的间隔,默认4dp-->
<attr format="dimension" name="bl_indicatorSpace"/>
<!--索引器的左侧边距,默认16dp-->
<attr format="dimension" name="bl_indicatorMarginLeft"/>
<!--索引器的右侧边距,默认0dp-->
<attr format="dimension" name="bl_indicatorMarginRight"/>
<!--索引器的底部边距,默认11dp-->
<attr format="dimension" name="bl_indicatorMarginBottom"/>
<!--索引器的对齐方式,默认left-->
<attr format="enum" name="bl_indicatorGravity">
<enum name="left" value="0"/>
<enum name="center" value="1"/>
<enum name="right" value="2"/>
</attr>
<!--轮播图之间的间距,默认是10dp-->
<attr format="dimension" name="bl_itemSpace"/>
<!--图片缩放系数,默认是1.2F-->
<attr format="float" name="bl_centerScale"/>
<!--轮播速度,默认是1.0F-->
<attr format="float" name="bl_moveSpeed"/>
</declare-styleable>
为轮播条设置常用事件
轮播到某一项的事件
在 MainActivity 的 onCreate() 方法中添加如下代码即可完成 item 改变事件:
mBl.setOnIndicatorIndexChangedListener(new BannerLayout.OnIndicatorIndexChangedListener() {
@Override
public void onIndexChanged(int position) {
XToast.normal(MainActivity.this,"轮播到了第 "+position+" 个" ).show();
}
});
为 item 添加点击事件
与 RecyclerView 一样没有直接为 BannerLayout 设置 setItemListener 事件,我们可以在 adapter 中为 item 中的 imageView 设置点击事件,然后再在 activity 中实现该点击事件。
作者已经为我们定义了 item 点击的 接口 : BannerLayout.OnBannerItemClickListener 。
首先我们需要改造一下 BannerAdapter :
public class BannerAdapter extends RecyclerView.Adapter<BannerAdapter.BannerViewHolder>{
private String[] urls;
private Context context;
//轮播条的 item 点击事件
private BannerLayout.OnBannerItemClickListener onBannerItemClickListener;
public BannerAdapter(Context context, String[] urls){
this.urls = urls;
this.context = context;
}
//给 activity 提供设置 item 点击事件的方法
public void setOnBannerItemClickListener(BannerLayout.OnBannerItemClickListener itemClickListener){
this.onBannerItemClickListener = itemClickListener;
}
@NonNull
@Override
public BannerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.banner_item, parent, false);
return new BannerViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull BannerViewHolder holder, final int position) {
ImageView imageView = holder.imageView;
ImageLoader.get().loadImage(imageView, urls[position]);
//由于每个 item 就一张图片,所以我们直接给 item 中的imageView 添加点击事件,即表示
//banner 中的某一个 item 被点击。
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onBannerItemClickListener.onItemClick(position);
}
});
}
@Override
public int getItemCount() {
return urls.length;
}
class BannerViewHolder extends RecyclerView.ViewHolder{
ImageView imageView;
public BannerViewHolder(@NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.iv_item);
}
}
}
在 MainActivity 中,需要实现 BannerLayout.OnBannerItemClickListener 接口,并调用 BannerAdapter 的 setOnBannerItemClickListener() 方法设置点击事件即可,完整代码如下:
public class BannerAdapter extends RecyclerView.Adapter<BannerAdapter.BannerViewHolder>{
private String[] urls;
private Context context;
//轮播条的 item 点击事件
private BannerLayout.OnBannerItemClickListener onBannerItemClickListener;
public BannerAdapter(Context context, String[] urls){
this.urls = urls;
this.context = context;
}
//给 activity 提供设置 item 点击事件的方法
public void setOnBannerItemClickListener(BannerLayout.OnBannerItemClickListener itemClickListener){
this.onBannerItemClickListener = itemClickListener;
}
@NonNull
@Override
public BannerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.banner_item, parent, false);
return new BannerViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull BannerViewHolder holder, final int position) {
ImageView imageView = holder.imageView;
ImageLoader.get().loadImage(imageView, urls[position]);
//由于每个 item 就一张图片,所以我们直接给 item 中的imageView 添加点击事件,即表示
//banner 中的某一个 item 被点击。
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onBannerItemClickListener.onItemClick(position);
}
});
}
@Override
public int getItemCount() {
return urls.length;
}
class BannerViewHolder extends RecyclerView.ViewHolder{
ImageView imageView;
public BannerViewHolder(@NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.iv_item);
}
}
}
2、 通过 ViewPagerBanner 实现的轮播条
对于我们来讲,我们可以不用关心作者是如何实现轮播条的。在这里我们先不讨论怎么实现的,我们先只学习怎么使用。
SimpleImageBanner 的使用
SimpleImageBanner 相对于上面讲的 BannerLayout 功能更加强大。如果我们要给每一项添加一个标题的话,BannerLayout 尚不支持,我们只能在 item view 中自己实现,而 SimpleImageBanner 可以直接设置标题,并且不需要我们设置 adapter,是不是简单很多呢。接下来,我们将完成一个小示例。
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
tools:context=".MainActivity">
<com.xuexiang.xui.widget.banner.widget.banner.SimpleImageBanner
android:id="@+id/sib_simple_banner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
app:bb_indicatorGravity="RIGHT"
app:bb_indicatorHeight="4dp"
app:bb_indicatorWidth="10dp"
app:bb_scale="0.5625" />
</LinearLayout>
MainActivity.java:
public class MainActivity extends AppCompatActivity {
private SimpleImageBanner mSimpleImageBanner;
//banner 中的标题
public static String[] titles = new String[]{
"伪装者:胡歌演绎'痞子特工'",
"无心法师:生死离别!月牙遭虐杀",
"花千骨:尊上沦为花千骨",
"综艺饭:胖轩偷看夏天洗澡掀波澜",
"碟中谍4:阿汤哥高塔命悬一线,超越不可能",
};
//banner 的图片资源
public static String[] urls = new String[]{//640*360 360/640=0.5625
"http://photocdn.sohu.com/tvmobilemvms/20150907/144160323071011277.jpg",//伪装者:胡歌演绎"痞子特工"
"http://photocdn.sohu.com/tvmobilemvms/20150907/144158380433341332.jpg",//无心法师:生死离别!月牙遭虐杀
"http://photocdn.sohu.com/tvmobilemvms/20150907/144160286644953923.jpg",//花千骨:尊上沦为花千骨
"http://photocdn.sohu.com/tvmobilemvms/20150902/144115156939164801.jpg",//综艺饭:胖轩偷看夏天洗澡掀波澜
"http://photocdn.sohu.com/tvmobilemvms/20150907/144159406950245847.jpg",//碟中谍4:阿汤哥高塔命悬一线,超越不可能
};
private List<BannerItem> mData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
mSimpleImageBanner = findViewById(R.id.sib_simple_banner);
sib_simple_usage();
}
private void sib_simple_usage() {
mSimpleImageBanner.setSource(mData)
.setOnItemClickListener(new BaseBanner.OnItemClickListener<BannerItem>() {
@Override
public void onItemClick(View view, BannerItem item, int position) {
}
})
.setIsOnePageLoop(false)//设置当页面只有一条时,是否轮播
.startScroll();//开始滚动
}
private void initData(){
mData = new ArrayList<>(urls.length);
for (int i = 0; i < urls.length; i++) {
BannerItem item = new BannerItem();
item.imgUrl = urls[i];
item.title = titles[i];
mData.add(item);
}
}
}
就这么简单,一个带标题的轮播条就完成了。
可以使用下面的方法来设置标题的颜色和大小。
mSimpleImageBanner.setTextColor()
mSimpleImageBanner.setTextSize()
app:bb_indicatorGravity="RIGHT"
bb_indicatorGravity 用于设置 指示器的位置,如果指示器在右边,标题就在左边。
还可以设置指示器的图片资源:
mSimpleImageBanner
.setIndicatorStyle(0)//设置指示器样式,在设置指示器资源时不能少
.setIndicatorSelectorRes(R.drawable.ic_banner_dot_unselect,R.drawable.ic_banner_dot_select)
对应的 xml 属性:
app:bb_indicatorSelectRes="@drawable/ic_banner_dot_select"
app:bb_indicatorStyle="DRAWABLE_RESOURCE"
app:bb_indicatorUnselectRes="@drawable/ic_banner_dot_unselect"
设置指示器动画:
.setSelectAnimClass(ZoomInEnter.class)//设置动画
RadiusImageBanner
该轮播条 的四个角是有圆弧的。
<com.xuexiang.xuidemo.widget.RadiusImageBanner
android:id="@+id/rib_simple_usage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:bb_barPaddingBottom="10dp"
app:bb_scale="0.4317" />
它的用法与 SimpleImageBanner 一样。
SimpleTextBanner
该轮播条只进行文字轮播,不能为其设置图片。
该轮播条的使用很简单,就不做过多阐述了。
<com.xuexiang.xui.widget.banner.widget.banner.SimpleTextBanner
android:id="@+id/stb_simple_textBanner"
android:layout_marginTop="50dp"
android:layout_width="match_parent"
android:layout_height="35dp"
app:bb_isIndicatorShow="false" />
mSimpleTextBanner
.setSource(titleList)
.setOnItemClickListener(new BaseBanner.OnItemClickListener<String>() {
@Override
public void onItemClick(View view, String item, int position) {
}
})
.startScroll();
示例项目的源代码我托管到 github ,欢迎大家查看。
RecyclerViewBanner 的代码在 bannerMoudle 中;SimpleImageBanner 的代码在 viewpagerbanner 中。