一、简介

Banner能实现循环播放多个广告图片和手动滑动循环等功能。因为原生ViewPager并不支持循环翻页, 要实现循环还得需要自己去动手。Banner框架可以进行不同样式、不同动画设置, 以及完善的api方法能满足大部分软件首页轮播图效果的需求。

有一篇博客讲了一些,可以参考banner框架,一个比较齐全的框架;

此项目的Github地址:链接。

本篇教程依然涉及一些其他方面的东西,如果有问题,可以参考我之前的系列文章。

二、添加依赖

  1. build.gradle中添加依赖:

    dependencies{compile 'com.youth.banner:banner:1.4.9'  //最新版本
    }
    
  2. 添加权限:

    <!-- if you want to load images from the internet -->
    <uses-permission android:name="android.permission.INTERNET" /> <!-- if you want to load images from a file OR from the internet -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    

三、解锁技能

1. 加载数据和刷新数据:

  • 首先,添加我们MainActivity的布局文件,里面含有一个SwipeRefreshLayout,包裹RecyclerView,SwipeRefreshLayout用来实现下拉刷新。

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="wrap_content"tools:context="com.ping.bannerdemo.activity.MainActivity"><android.support.v4.widget.SwipeRefreshLayoutandroid:id="@+id/swipeRefreshLayout"android:layout_width="match_parent"android:layout_height="wrap_content"><android.support.v7.widget.RecyclerViewandroid:id="@+id/recyclerView"android:layout_width="match_parent"android:layout_height="wrap_content"></android.support.v7.widget.RecyclerView></android.support.v4.widget.SwipeRefreshLayout></LinearLayout>
    
  • 然后,我们要在RecyclerView中添加俩种布局,一个Header存放Banner,另一个则是正常的item布局。先放上俩个布局的内容。

    //header.xml
    <?xml version="1.0" encoding="utf-8"?>
    <com.youth.banner.Bannerxmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/banner"android:layout_width="match_parent"android:layout_height="match_parent"/>//item_recycler.xml
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"><TextViewandroid:padding="5dp"android:gravity="center"android:id="@+id/tv_item"android:textSize="20dp"android:textColor="#000"android:layout_width="match_parent"android:layout_height="wrap_content"/></LinearLayout>
    

    要添加俩种布局,得在Adapter中实现,这里可以全面的看一下各种LayoutManager中怎么添加header布局,戳这。这里,我就用了文中的第一个,主要方法就是根据不同的ViewType返回不同的ViewHolder。通过setter方法将header的view注入进adapter。先来看一下adapter吧。

    public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {public static final int TYPE_HEADER = 0;public static final int TYPE_NORMAL = 1;private View mHeaderView;private String[] mData;private Context mContext;public void setHeaderView(View headerView) {mHeaderView = headerView;}public MyAdapter(Context context, String[] data) {mContext = context;mData = data;}//根据pos返回不同的ItemViewType@Overridepublic int getItemViewType(int position) {if (mHeaderView == null) return TYPE_NORMAL;if (position == 0) return TYPE_HEADER;return TYPE_NORMAL;}//在此根据ItemViewType来决定返回何种ViewHolder@Overridepublic MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {if (mHeaderView != null && viewType == TYPE_HEADER)return new MyViewHolder(mHeaderView);View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycler, parent, false);return new MyViewHolder(view);}@Overridepublic void onBindViewHolder(MyViewHolder holder, int position) {if(getItemViewType(position) == TYPE_HEADER) return;final int pos = getRealPosition(holder);final String data = mData[pos];if(holder instanceof MyViewHolder) {((MyViewHolder) holder).mTvItem.setText(data);}}private int getRealPosition(RecyclerView.ViewHolder holder) {int position = holder.getLayoutPosition();return mHeaderView == null ? position : position - 1;}//返回正确的item个数@Overridepublic int getItemCount() {return mHeaderView == null ? mData.length : mData.length + 1;}public class MyViewHolder extends RecyclerView.ViewHolder {@BindView(R.id.tv_item)TextView mTvItem;public MyViewHolder(View itemView) {super(itemView);if(itemView == mHeaderView)return;ButterKnife.bind(this, itemView);}}
    }
    
  • 看完Adapter,我们要看看在哪里对headerview进行set了。MainActivity中我们渲染出header的布局,然后通过setHeaderView将view传递进去即可。

    //渲染header布局
    View header = LayoutInflater.from(this).inflate(R.layout.header, null);
    mBanner = (Banner) header.findViewById(R.id.banner);
    //设置banner的高度为手机屏幕的四分之一
    mBanner.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, App.H/4));
    //arrays资源文件存放banner图片的url地址
    String[] data = getResources().getStringArray(R.array.demo_list);mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
    myAdapter = new MyAdapter(this, data);
    //设置headerview
    myAdapter.setHeaderView(mBanner);
    mRecyclerView.setAdapter(myAdapter);
    
  • 然而启动banner:

    mBanner.setImages(App.images).setImageLoader(new GlideImageLoader()).start();
    

    这里new了一个GlideImageLoader的实例,官方给出的各种图片加载库加载的方式如下:

    public class GlideImageLoader extends ImageLoader {@Overridepublic void displayImage(Context context, Object path, ImageView imageView) {/**注意:1.图片加载器由自己选择,这里不限制,只是提供几种使用方法2.返回的图片路径为Object类型,由于不能确定你到底使用的那种图片加载器,传输的到的是什么格式,那么这种就使用Object接收和返回,你只需要强转成你传输的类型就行,切记不要胡乱强转!*/eg://Glide 加载图片简单用法Glide.with(context).load(path).into(imageView);//Picasso 加载图片简单用法Picasso.with(context).load(path).into(imageView);//用fresco加载图片简单用法,记得要写下面的createImageView方法Uri uri = Uri.parse((String) path);imageView.setImageURI(uri);}//提供createImageView 方法,如果不用可以不重写这个方法,主要是方便自定义ImageView的创建@Overridepublic ImageView createImageView(Context context) {//使用fresco,需要创建它提供的ImageView,当然你也可以用自己自定义的具有图片加载功能的ImageViewSimpleDraweeView simpleDraweeView=new SimpleDraweeView(context);return simpleDraweeView;}
    }
    
  • 下拉时,我们需要在轮播图中更新数据,我们需要为SwipeRefreshLayout添加onRefresh()事件:

    private Handler mHandler = new Handler() {public void handleMessage(android.os.Message msg) {switch (msg.what) {case REFRESH_COMPLETE:String[] urls = getResources().getStringArray(R.array.url);List list = Arrays.asList(urls);List arrayList = new ArrayList(list);//把新的图片地址加载到BannermBanner.update(arrayList);//下拉刷新控件隐藏mSwipeRefreshLayout.setRefreshing(false);break;}}
    };.......mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {@Overridepublic void onRefresh() {mHandler.sendEmptyMessageDelayed(REFRESH_COMPLETE, 2000);}
    });
    
  • 在Banner中,我们设置了高度为四分之一屏幕,屏幕的高度是在app一初始化就获取到的,同时,在这里我们用了一个Android Crash的框架Recovery,也没必要用,就是可以把错误反馈到手机上。可以参考这个博客。

    public class App extends Application{public static int H;public static List<?> images=new ArrayList<>();public static List<String> titles=new ArrayList<>();@Overridepublic void onCreate() {super.onCreate();initBanner();}private void initBanner() {H = getScreenH(this);Recovery.getInstance().debug(true).recoverInBackground(false).recoverStack(true).mainPage(MainActivity.class).init(this);String[] urls = getResources().getStringArray(R.array.url4);String[] tips = getResources().getStringArray(R.array.title);List list = Arrays.asList(urls);images = new ArrayList<>(list);titles= Arrays.asList(tips);}/*** 获取屏幕高度* @param aty* @return*/public int getScreenH(Context aty){DisplayMetrics dm = aty.getResources().getDisplayMetrics();return dm.heightPixels;}
    }
    
  • 最后,看一下我们的运行效果:

2. Banner的各种动画:

  • Banner的动画都在com.youth.banner.transformer包下,包含下面的这些,相信看名字就知道大概什么效果。

    com.youth.banner.transformer.AccordionTransformer;
    com.youth.banner.transformer.BackgroundToForegroundTransformer;
    com.youth.banner.transformer.CubeInTransformer;
    com.youth.banner.transformer.CubeOutTransformer;
    com.youth.banner.transformer.DefaultTransformer;
    com.youth.banner.transformer.DepthPageTransformer;
    com.youth.banner.transformer.FlipHorizontalTransformer;
    com.youth.banner.transformer.FlipVerticalTransformer;
    com.youth.banner.transformer.ForegroundToBackgroundTransformer;
    com.youth.banner.transformer.RotateDownTransformer;
    com.youth.banner.transformer.RotateUpTransformer;
    com.youth.banner.transformer.ScaleInOutTransformer;
    com.youth.banner.transformer.StackTransformer;
    com.youth.banner.transformer.TabletTransformer;
    com.youth.banner.transformer.ZoomInTransformer;
    com.youth.banner.transformer.ZoomOutSlideTransformer;
    com.youth.banner.transformer.ZoomOutTranformer;
    
  • 通过setBannerAnimation()来设置动画。例如,设置为方块滚动;

     ......mBanner.setImages(App.images).setBannerAnimation(CubeOutTransformer.class).setImageLoader(new GlideImageLoader()).start();......
    
  • 效果如下:

3. Banner的各种内置样式 :

  • Banner内置的样式有以下几种,

    BannerConfig.NOT_INDICATOR       //没有指示器
    BannerConfig.CIRCLE_INDICATOR    //圆圈指示器(默认)
    BannerConfig.NUM_INDICATOR       //数字圆盘指示器
    BannerConfig.NUM_INDICATOR_TITLE //数字圆盘带标题的
    BannerConfig.CIRCLE_INDICATOR_TITLE  //圆圈指示器附带标题
    BannerConfig.CIRCLE_INDICATOR_TITLE_INSIDE  //区别于上一个,圆圈指示器在标题栏里
    
  • 这里我们实现一下圆圈指示器附带标题的样式:

    ArrayList<String> titles = new ArrayList<>(Arrays.asList(new String[]{"first title", "second title", "third title", "fourth title"}));
    mBanner.setImages(App.images).setBannerAnimation(CubeOutTransformer.class).setBannerStyle(BannerConfig.CIRCLE_INDICATOR_TITLE).setBannerTitles(titles).setImageLoader(new GlideImageLoader()).start();
    
  • 效果如下:

4. Banner自定义样式:

  • 自定义banner的属性:

    Attributes forma describe
    delay_time integer 轮播间隔时间,默认2000
    scroll_time integer 轮播滑动执行时间,默认800
    is_auto_play boolean 是否自动轮播,默认true
    title_background color reference
    title_textcolor color 标题字体颜色
    title_textsize dimension 标题字体大小
    title_height dimension 标题栏高度
    indicator_width dimension 指示器圆形按钮的宽度
    indicator_height dimension 指示器圆形按钮的高度
    indicator_margin dimension 指示器之间的间距
    indicator_drawable_selected reference 指示器选中效果
    indicator_drawable_unselected reference 指示器未选中效果
    image_scale_type enum 和imageview的ScaleType作用一样

    参照上述属性,现在对指示器设置高宽和选中颜色:

    <com.youth.banner.Bannerxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/banner"android:layout_width="match_parent"android:layout_height="match_parent"app:indicator_drawable_selected="@color/colorAccent"app:indicator_drawable_unselected="@android:color/white"app:indicator_height="4dp"app:indicator_margin="4dp"app:indicator_width="20dp"/>
    
  • 实现效果:

四、Demo下载:

源码下载

个人公众号:每日推荐一篇技术博客,坚持每日进步一丢丢…欢迎关注,想建个微信群,主要讨论安卓和Java语言,一起打基础、用框架、学设计模式,菜鸡变菜鸟,菜鸟再起飞,愿意一起努力的话可以公众号留言,谢谢…

Android框架之路——Banner实现轮播图(RecyclerView添加Header)相关推荐

  1. Android三方框架banner实现轮播图

    Android三方框架banner实现轮播图 关于 效果图 第一步,添加引用 第二步,新增实体类及测试数据 第三步,添加banner实例控件,修改主界面代码 自定义图片+标题轮播图 效果图 你以为到这 ...

  2. ElementUi轮播图走马灯添加图片

    ElementUi轮播图走马灯添加图片 官网例子 改造适用 效果 官网例子 这里我们拿官网的例子作为讲解 链接: 官网. 代码 <template><el-carousel :int ...

  3. Android 加载圆角的图片轮播图

    图片轮播图相信大家有不会陌生,主要用于展示广告.本篇文章是基于第三方Banner框架实现图片轮播.大家可以去看看我之前的文章:Android 广告轮播图(最简单的实现),看看是怎么基础实现. 本篇文章 ...

  4. 自定义组合控件:Banner、轮播图、广告栏控件

    1. 项目概述 这里,我们使用自定义组合控件实现一个自动轮播的广告条,也叫轮播图,完整版的效果图如下图所示.其实,这就是我们经常见到的滚动广告,默认情况下每隔N 秒会自动滚动,用手指左右滑动时也会切换 ...

  5. 微信小程序轮播图单独添加图片、修改轮播图图片、单独修改某张图片

    小老弟上课的基本见解,有错误欢迎大牛们指正 <!--pages/swiper/swiper.wxml--> <text>pages/swiper/swiper.wxml< ...

  6. Android Banner(无限轮播图)控件的简单使用(网络数据OkHttp3)

    一言不合就上图 banner是第三方集成好的直接注入依赖就可以用 老套路先注入依赖: //banner这个版本才是王道(我的studio是2.3.3)compile 'com.youth.banner ...

  7. android 卡片轮播图,android自定义view之卡片式轮播图

    前言 Android View体系是界面编程的核心,他的重要性不亚于Android四大组件.能够熟练的编写符合需求自定义VIEW是一个android程序员进阶的重要标志,在很多的企业招聘中都会在任职需 ...

  8. 第三方开源库:轮播图:Banner/Kanner

    Banner 简介 轮播图控件,支持:标题.标题+指示器.标题+数字.标题+指示器垂直显示. github地址:youth5201314/banner 效果图: 步骤 github中readme.md ...

  9. banner 获取当前指示物_Android轮播图图片的本地保存及读取

    一.轮播图控件及图片加载 对于Android端的轮播图控件,我这边选用的是banner库 //轮播图 compile 'com.youth.banner:banner:1.4.9' //Glide c ...

最新文章

  1. 李洪强经典面试题10
  2. C++library Sort库排序的实现算法(附完整源码)
  3. PHP增加$_ENV变量
  4. MySQL——高阶语句(中)
  5. 女朋友掉水里,各类程序猿怎么救?
  6. WIN10 开启右键 命令提示符
  7. java拉丁正方形_LeetCode JAVA解题---824. 山羊拉丁文
  8. 另类架构师:在国企涂肥皂水、考研被调剂、在阿里跟十八罗汉当同事……
  9. simulink模块使用记录2-EnabledSubsystem/merge
  10. sql删除语句_推荐强大开源的数据库SQL语句审核平台,再也不用担心删除跑路了!...
  11. CCIE基础知识之EIGRP 二
  12. JavaScript中清空数组最有效的三种方法
  13. Atitit 效率提升法细则 v3 t028.docx Atitit 提升效率细则 目录 1. 目标 2 1.1. 配置化增加扩展性 尽可能消除编译 方便增加 调整业务逻辑 2 1.2. 统一接口
  14. SLAM--G2o实现BA优化
  15. 人人网普通登录源码爬取
  16. 英制BSW 美制UNC 螺牙的理解
  17. 计算机基础知识上机题,计算机基础上机题库.doc
  18. 每个前端工程师都应该了解的图片知识
  19. 给定两个字符串 s 和 t,它们只包含小写字母。
  20. PyTorch 加载预训练权重

热门文章

  1. mount:special device does not exist (a path prefix is not a directory)
  2. mysql 自动生成时间戳
  3. svg文件解析(python)
  4. 他来了他来了,Hadoop序列化和切片机制了解一下?
  5. 【智能驾驶】最全、最强的无人驾驶技术学习路线
  6. 对象存储2:数据存储类型-文件存储、块存储、对象存储详解
  7. simulink/stateflow 纯电动+4档变速箱动力性经济性仿真模型 包含vcu控制及换档控制模型,可实现最高车速 最大爬坡度 加速时间
  8. vue 组件内引入外部在线js、css
  9. 侍魂qq最新服务器,2018腾讯发布火影、圣斗士星矢、侍魂等20款新手游
  10. 3年半工作经验女程序员,聊聊程序员的薪水、工作内容和发展前景