首先在app中的build.gradle中添加以下依赖,banner为轮播图框架,glide为图片加载框架。
implementation 'com.youth.banner:banner:1.4.9'
implementation 'com.github.bumptech.glide:glide:4.7.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'
//网络请求用到以下依赖okhttp及okhttputil
implementation 'com.squareup.okhttp3:okhttp:4.3.0'
implementation 'com.squareup.okio:okio:2.4.3'
implementation 'com.zhy:okhttputils:2.6.2'
然后编写需要使用轮播图的布局,请根据自己的项目需求修改,简单示例如下:
<com.youth.banner.Banner
android:id="@+id/banner"
android:layout_width="match_parent"
android:layout_height="180dp"
/>
由于不同项目轮播图本身有不同比例要求,所以建议不要在布局文件中 写死,稍候我的示例中将会用代码动态修改banner控件的横宽比。
之后理一下轮播图的业务逻辑流程:①打开APP时,从SharedPreferences中获取上一次请求服务器获得的轮播图数据json并加载,若SharedPreferences没有数据则手动写入默认数据。 ②请求服务器获取最新的轮播图数据,成功请求后将获取到的json存入SharedPreferences。 ③将请求到的新数据进行解析并更新轮播图
接下来我将和banner有关的所有代码直接贴出,重要部分会在注释中说明:
首先添加以下所需的全局变量:
private Banner banner;
private ArrayList<String> list_path;
private ArrayList<String> list_title;
private ArrayList<String> list_href;
并且类需要继承OnBannerListener以设置点击事件:
public class BannerDemo extends AppCompatActivity implements OnBannerListener
然后再oncreate方法中设置banner控件宽高比以及调用初始化和更新方法:
banner = (Banner)findViewById(R.id.banner);
WindowManager wm1 = getActivity().getWindowManager();
int width = wm1.getDefaultDisplay().getWidth();
LinearLayout.LayoutParams linearParams =(LinearLayout.LayoutParams) banner.getLayoutParams();
linearParams.width = width;
linearParams.height = width*9/16;
banner.setLayoutParams(linearParams); //将轮播图控件设置为16/9的比例
initView();
updateBanner();
最后完成初始化和更新方法并设置点击事件即可:
private void updateBanner(){
String host = new Defines().SERVER_HOST+"getBanner";
OkHttpUtils
.post()
.url(host)
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int id) {
Toasty.error(getActivity(), "服务器请求失败", Toast.LENGTH_SHORT, true).show();
}
@Override
public void onResponse(String response, int id) {
try {
JSONObject jsonObject = new JSONObject(response);
int code = jsonObject.getInt("code");
if (code==200) {
//若请求成功则清空当前数据并重新写入以及存入SharedPreferences
list_path.clear();
list_href.clear();
list_title.clear();
JSONArray dataArray = jsonObject.getJSONArray("data");
final SharedPreferences sp = getActivity().getSharedPreferences("banner", Context.MODE_PRIVATE);
sp.edit().putString("jsonList",dataArray.toString()).commit();
ArrayList<String> update_list_path = new ArrayList<>();
ArrayList<String> update_list_title = new ArrayList<>();
ArrayList<String> update_list_href = new ArrayList<>();
if(dataArray.length()!=0){
for(int i=0;i<dataArray.length();i++){
JSONObject thisBanner = dataArray.getJSONObject(i);
update_list_title.add(thisBanner.getString("title"));
update_list_path.add(thisBanner.getString("img_url"));
update_list_href.add(thisBanner.getString("href"));
}
}else{
update_list_title.add("No_Banner_Title");
update_list_path.add("No_Banner_Url");
update_list_href.add("No_Banner_Href");
}
list_path = update_list_path;
list_title = update_list_title;
list_href = update_list_href;
//这里注意banner的update方法中不能使用全局变量参数,这里的update_list_path和,update_list_title都是重新定义的变量
banner.update(update_list_path,update_list_title);
} else {
Toasty.error(getActivity(),jsonObject.getString("msg"), Toast.LENGTH_SHORT, true).show();
}
} catch (JSONException e) {
e.printStackTrace();
Toasty.error(getActivity(),"轮播图获取失败",Toast.LENGTH_LONG).show();
}
}
});
}
private void initView(){
//放图片地址的集合
list_path = new ArrayList<>();
//放标题的集合
list_title = new ArrayList<>();
//放链接的集合
list_href = new ArrayList<>();
final SharedPreferences sp = getActivity().getSharedPreferences("banner", Context.MODE_PRIVATE);
try {
String bannerArrayJson = sp.getString("jsonList",null);
if(bannerArrayJson!=null){
JSONArray dataArray = new JSONArray(bannerArrayJson);
if(dataArray.length()!=0){
for(int i=0;i<dataArray.length();i++){
JSONObject thisBanner = dataArray.getJSONObject(i);
list_title.add(thisBanner.getString("title"));
list_path.add(thisBanner.getString("img_url"));
list_href.add(thisBanner.getString("href"));
}
}else{
list_path.add("No_Banner_Url");
list_title.add("No_Banner_Title");
list_href.add("No_Banner_Href");
}
}else{
list_path.add("No_Banner_Url");
list_title.add("No_Banner_Title");
list_href.add("No_Banner_Href");
}
} catch (JSONException e) {
}
//设置内置样式,共有六种可以点入方法内逐一体验使用。
banner.setBannerStyle(2);
//设置图片加载器,图片加载器在下方
banner.setImageLoader(new MyLoader());
//设置图片网址或地址的集合
banner.setImages(list_path);
//设置轮播的动画效果,内含多种特效,可点入方法内查找后内逐一体验
banner.setBannerAnimation(Transformer.DepthPage);
//设置轮播图的标题集合
banner.setBannerTitles(list_title);
//设置轮播间隔时间
banner.setDelayTime(3000);
//设置是否为自动轮播,默认是“是”。
banner.isAutoPlay(true);
//设置指示器的位置,小点点,左中右。
banner.setIndicatorGravity(BannerConfig.CENTER)
//以上内容都可写成链式布局,这是轮播图的监听。比较重要。方法在下面。
.setOnBannerListener(this)
//必须最后调用的方法,启动轮播图。
.start();
}
//设置点击事件
@Override
public void OnBannerClick(int position) {
if(!list_href.get(position).equals("No_Banner_Href")){
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(list_href.get(position)));
startActivity(intent);
}else{
Toasty.info(getActivity(),"轮播图加载失败",Toast.LENGTH_SHORT).show();
}
}
//自定义的图片加载器,使用glide加载图片,placeholder和error分别是加载和加载失败的占位图
private class MyLoader extends ImageLoader {
@Override
public void displayImage(Context context, Object path, ImageView imageView) {
RequestOptions options = RequestOptions.centerInsideTransform().placeholder(R.drawable.loadingbanner).error(R.drawable.loadingbanner);
Glide.with(context).load((String) path).apply(options).into(imageView);
}
}