在开始我的博客之前,我为大家准备了几个非常热门的app的主界面的截图。不难发现,这些apps都用到了轮播图(红色圈出来的部分),实现循环播放多个广告图片和手动滑动循环等功能。如今,在大部分的apps中,轮播图基本已经是随处可见。
那提到轮播图的制作,很多人应该最先想到的Android Studio自身的viewpage的控件,但是viewpage的许多功能都需要通过自定义来实现,工作量比较大,实现起来比较繁琐。因此我就“不重复造轮子”,不用viewpage来制作,主要介绍的是我在github上发现两款热门的开源框架:
官方Github地址:https://github.com/youth5201314/banner/tree/release-1.4.10
官方Github地址:https://github.com/daimajia/AndroidImageSlider
这两款开源框架不仅仅功能十分强大,重点是十分简单易用,对于新手来说容易上手,对于老手来说可以提高效率,接下来就来详细介绍一下这两个框架的具体实现。
dependencies{
//图片轮播框架
implementation 'com.youth.banner:banner:1.4.10'
//图片加载框架
implementation 'com.github.bumptech.glide:glide:3.7.0'
}
目前banner框架最新版本已经达到2.0,实现的功能更加强大,有兴趣的朋友可以自行探索。我采用的是1.0版本中最新的1.4.10。
需要特别注意的一点是banner本身不提供图片加载功能,因此我们除了需要用到banner框架自身外,还需要用到图片加载的相关框架,图片加载的框架有很多,这边用到的是glide框架。
这里讲到的权限设置主要是和导入图片资源有关,如果你想以链接的方式直接从网络上获取图片资源或者是从文件中获取图片资源则需要在AndroidManifest.xml中进行如下设置。
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Banner的属性完全可以按着个人喜好来自定义。当然跳过这一步也是可以的,但是这种情况下,需要在Activity或者Fragment中new Banner()。以下是我在布局文件中简单的定义了一个Banner:
<com.youth.banner.Banner
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/banner"
android:layout_width="match_parent"
android:layout_height="250dp" />
如果想对banner的一些小部件进行自定义,那就必须在布局文件中进行定义。在自定义操作之前,先在布局文件中加入这行代码:
xmlns:custom="http://schemas.android.com/apk/res-auto"
只有加入了这行代码以后,才能完成以下的自定义banner布局编写,举几个简单的例子:
//设置标题字体颜色
custom:title_textcolor="***";
//设置标题字体大小
custom:title_textsize=**sp;
//设置标题栏高度
custom:title_height=**dp;
//设置圆形指示器宽度
custom:indicator_width=**dp
//设置圆形指示器高度
custom:indicator_height=**dp
//设置圆形指示器间距
custom:indicator_margin=**dp
//还可以设置指示器选中效果、指示器未选中效果、标题背景颜色等等...
先附上完整代码:
package com.example.mybanner;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.widget.ImageView;
import android.widget.Toast;
import com.youth.banner.Banner;
import com.youth.banner.BannerConfig;
import com.youth.banner.Transformer;
import com.youth.banner.listener.OnBannerListener;
import com.youth.banner.loader.ImageLoader;
import com.bumptech.glide.Glide;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
//定义图片加载器
public class MyImageLoader extends ImageLoader {
@Override
public void displayImage(Context context, Object path, ImageView imageView) {
Glide.with(context).load(path).into(imageView);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Banner banner = (Banner) findViewById(R.id.banner);
//初始化图片数据
List images = new ArrayList();
images.add(R.mipmap.a);
images.add(R.mipmap.b);
images.add(R.mipmap.c);
images.add(R.mipmap.d);
//初始化标题数据
List titles = new ArrayList();
titles.add("《绿皮书》:如果我不像黑人,又不是白人,你告诉我,我到底算是什么");
titles.add("《何以为家》:一部所有中国父母都应该去看的影片");
titles.add("《想见你》:台湾偶像剧的突破之作");
titles.add("《都挺好》:结局真的是大团圆吗?那是和解也是妥协");
//设置图片加载器
banner.setImageLoader(new MyImageLoader());
//设置图片集合
banner.setImages(images);
//设置标题集合(当banner样式有显示title时)
banner.setBannerTitles(titles);
//设置轮播的动画效果
banner.setBannerAnimation(Transformer.ZoomOutSlide);
//设置自动轮播,默认为true
banner.isAutoPlay(true);
//设置轮播时间(设置2.5秒切换下一张图片)
banner.setDelayTime(2500);
//设置banner显示样式(带标题的样式)
banner.setBannerStyle(BannerConfig.CIRCLE_INDICATOR_TITLE_INSIDE);
//设置指示器位置(当banner模式中有指示器时)
banner.setIndicatorGravity(BannerConfig.RIGHT);
//增加监听事件
banner.setOnBannerListener(new OnBannerListener() {
@Override
public void OnBannerClick(int position) {
Toast.makeText(MainActivity.this, "position"+position, Toast.LENGTH_SHORT).show();
}
});
//banner设置方法全部调用完毕时最后调用
banner.start();
}
}
我的代码中已经标有注释,如果还是不能理解的话,接下来逐一讲解几个重点部分:
在前面我提到过,banner自身是不带有图片加载功能的,因此我们需要自己编写一个图片加载器,图片加载的方法有很多,例如我用的Glide框架:
public class MyImageLoader extends ImageLoader {
@Override
public void displayImage(Context context, Object path, ImageView imageView) {
Glide.with(context).load(path).into(imageView);
}
又例如Picasso框架:(如果用Picasso,记得导入相关依赖哦)
public class MyImageLoader extends ImageLoader {
@Override
public void displayImage(Context context, Object path, ImageView imageView) {
Picasso.with(context).load(path).into(imageView);
}
初始化图片数据可以套用以下的模板:
List images = new ArrayList();
images.add(“图片链接”);//例如:images.add("https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=375356692,2997891437&fm=26&gp=0.jpg")
images.add(图片ID);//例如:images.add(R.mipmap.a)
标题数据也同理,只是将add()括号中的内容改为字符串类型而已。
banner的属性与方法在官方github中介绍了非常多,这也正是banner功能强大之处。我这里使用的仅仅是一部分:
//设置图片加载器
banner.setImageLoader(new MyImageLoader());
//设置图片集合
banner.setImages(images);
//设置标题集合(当banner样式有显示title时)
banner.setBannerTitles(titles);
//设置轮播的动画效果
banner.setBannerAnimation(Transformer.ZoomOutSlide);
//设置自动轮播,默认为true
banner.isAutoPlay(true);
//设置轮播时间(设置2.5秒切换下一张图片)
banner.setDelayTime(2500);
//设置banner显示样式(带标题的样式)
banner.setBannerStyle(BannerConfig.CIRCLE_INDICATOR_TITLE_INSIDE);
//设置指示器位置(当banner模式中有指示器时)
banner.setIndicatorGravity(BannerConfig.RIGHT);
//增加监听事件
banner.setOnBannerListener(new OnBannerListener() {
@Override
public void OnBannerClick(int position) {
Toast.makeText(MainActivity.this, "position"+position, Toast.LENGTH_SHORT).show();
}
});
//banner设置方法全部调用完毕时最后调用
banner.start();
方法:
setBannerAnimation()
那到此为止,基本的Banner框架的介绍就结束了,我简单做了一个类似于视频app的主页轮播图,接下来就看一下运行效果吧。
建议全部的依赖项目统一使用最新的版本,因为依赖的项目之间可能也会存在依赖,为了避免出现版本冲突问题,建议全部使用最新版。
dependencies {
implementation "com.android.support:support-v4:+"
implementation 'com.squareup.picasso:picasso:2.3.2'
implementation 'com.nineoldandroids:library:2.4.0'
implementation 'com.daimajia.slider:library:1.1.5@aar'
}
和Banner框架中讲到的一样,如果你想以链接的方式直接从网络上获取图片资源或者是从文件中获取图片资源则需要在AndroidManifest.xml中进行如下设置。
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
这一步和Banner一样有很多可以大显身手的地方,依旧自定义之前记得在布局文件中加上这一句代码:
xmlns:custom="http://schemas.android.com/apk/res-auto"
我简单自定义了一下SliderLayout,代码如下:
<com.daimajia.slider.library.SliderLayout
android:id="@+id/slider"
android:layout_width="match_parent"
android:layout_height="230dp"
//设置动画切换效果
custom:pager_animation="Accordion"
//设置动画是否自动循环
custom:auto_cycle="true"
//设置是否显示指示器
custom:indicator_visibility="visible"
//设置动画持续时间
custom:pager_animation_span="2500"
/>
同时对于指示器,也可以在布局文件中进行自定义,当然对于指示器的自定义并不是必须的,虽然我的这个项目中没有自定义指示器,但是附上两段自定义指示器的代码供大家参考:
第一种:基本上自定义指示器可以用的属性都在这列举出来了
<com.daimajia.slider.library.Indicators.PagerIndicator
android:id="@+id/custom_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
custom:selected_color="#0095BF"
custom:unselected_color="#55333333"
custom:selected_drawable="@drawable/bird"
custom:shape="oval"
custom:selected_padding_left="5dp"
custom:selected_padding_right="5dp"
custom:unselected_padding_left="5dp"
custom:unselected_padding_right="5dp"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
custom:selected_width="6dp"
custom:selected_height="6dp"
custom:unselected_width="6dp"
custom:unselected_height="6dp"
android:layout_marginBottom="40dp"
/>
第二种:懒人模式,采用AndroidImageSlider默认的模式来定义指示器,AndroidImageSlider共提供的三种模式:AndroidImageSlider_Corner_Oval_Orange,
AndroidImageSlider_Attractive_Rect_Blue,
AndroidImageSlider_Magnifier_Oval_Black
<com.daimajia.slider.library.Indicators.PagerIndicator
android:id="@+id/custom_indicator"
style="@style/AndroidImageSlider_Corner_Oval_Orange"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_marginBottom="20dp"
/>
另外需要注意的一个点是,如果有自定义指示器,那么需要把PagerIndicator嵌套在SliderLayout之中,举个例子:
<com.daimajia.slider.library.SliderLayout
...
>
<com.daimajia.slider.library.Indicators.PagerIndicator
...
/>
</com.daimajia.slider.library.SliderLayout>
AndroidImageSlider和Banner最大的不同的地方就在于它不需要自己编写图片加载器,另外可以选择初始化资源之后再加载资源,也可以选择直接在SliderView中加载资源,同时AndroidImageSlider提供两种功能,第一种就是单纯的只展示图片轮询,使用DefaultSliderView。第二种就是带描述的图片展示的TextSliderView,一般情况下我们都会使用第二种。
先附上完整代码:
package com.example.androidimageslider;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import com.daimajia.slider.library.SliderLayout;
import com.daimajia.slider.library.SliderTypes.BaseSliderView;
import com.daimajia.slider.library.SliderTypes.TextSliderView;
public class MainActivity extends AppCompatActivity {
SliderLayout sliderShow;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sliderShow = (SliderLayout) findViewById(R.id.slider);
TextSliderView textSliderView1 = new TextSliderView(this);
textSliderView1
.description("《我和我的祖国》:每一段历史都不应被遗忘")
.setScaleType(BaseSliderView.ScaleType.Fit)
.image(R.mipmap.a);
sliderShow.addSlider(textSliderView1);
TextSliderView textSliderView2 = new TextSliderView(this);
textSliderView2.description("《少年的你》:你保护世界,我保护你")
.setScaleType(BaseSliderView.ScaleType.Fit)
.image(R.mipmap.b);
sliderShow.addSlider(textSliderView2);
TextSliderView textSliderView3 = new TextSliderView(this);
textSliderView3.description("《叶问4》:甄子丹时代谢幕前的最后突围")
.setScaleType(BaseSliderView.ScaleType.Fit)
.image(R.mipmap.c);
sliderShow.addSlider(textSliderView3);
TextSliderView textSliderView4 = new TextSliderView(this);
textSliderView4.description("《安家》:食得人间烟火味,感受世间千百态")
.setScaleType(BaseSliderView.ScaleType.Fit)
.image(R.mipmap.d);
sliderShow.addSlider(textSliderView4);
// 设置动画效果(也可在xml中设置,例如custom:pager_animation="Accordion")
sliderShow.setPresetTransformer(SliderLayout.Transformer.Accordion);
// 设置指示器位置
sliderShow.setPresetIndicator(SliderLayout.PresetIndicators.Right_Bottom);
// 设置持续时间
sliderShow.setDuration(2500);
}
}
这一过程可以套用这个模板:
TextSliderView textSliderView = new TextSliderView(this);
textSliderView
.description("你的描述")
.setScaleType(BaseSliderView.ScaleType.Fit)
.image(你的图片);//可以是链接也可以是图片文件ID
sliderShow.addSlider(textSliderView);
这里与Banner类似同样可以设置许多的属性,具体可以参照官方Github深入研究,我在这里仅列出一小部分:
// 设置动画效果(也可在xml中设置,例如custom:pager_animation="Accordion")
sliderShow.setPresetTransformer(SliderLayout.Transformer.Accordion);
// 设置指示器位置
sliderShow.setPresetIndicator(SliderLayout.PresetIndicators.Right_Bottom);
// 设置持续时间
sliderShow.setDuration(2500);
方法:
setPresetTransformer()
相关值:Slider中共有16种动画效果
“Default”,“Accordion”,
“Background2Foreground”,
“CubeIn”,
“DepthPage”,
“Fade”,
“FlipHorizontal”,
“FlipPage”,
“Foreground2Background”,
“RotateDown”,
“RotateUp”,
“Stack”,
“Tablet”,
“ZoomIn”,
“ZoomOutSlide”,
“ZoomOut”;
方法:
setPresetIndicator()
相关值:
Center_Bottom(“Center_Bottom”,R.id.default_center_bottom_indicator),
Right_Bottom(“Right_Bottom”,R.id.default_bottom_right_indicator),
Left_Bottom(“Left_Bottom”,R.id.default_bottom_left_indicator),
Center_Top(“Center_Top”,R.id.default_center_top_indicator),
Right_Top(“Right_Top”,R.id.default_center_top_right_indicator),
至此,AndroidImageSlider的介绍也差不多结束了,同样我运用AndroidImageSlider做了另外一个类似于视频app的主页轮播图,最后一起来看一下运行效果吧。