美文网首页Android开发学习AndroidAndroid Other
Android智能下拉刷新框架-SmartRefreshLayo

Android智能下拉刷新框架-SmartRefreshLayo

作者: scwang90 | 来源:发表于2017-07-05 22:04 被阅读19430次

    框架?下拉刷新控件还能框架化?智能又怎么回事?二话不多少先上Demo效果图,咱们再来探个究竟。

    Github 传送门
    注意:本文仅仅是博客文章,主要用于项目介绍和宣传,由于发布时间关系,部分内容已经过期,详细使用文档请跳转 github


    Demo

    下载 APK-Demo

    如果手机上看不到图片,可以尝试

    项目演示

    个人首页 微博列表
    餐饮美食 个人中心

    刷新样式

    Delivery DropBox
    Refresh-your-delivery Dropbox-Refresh

    上面这两个是我自己实现的,下面的是我把github上其它优秀的Header进行的整理和集合还有优化:

    BezierRadar BezierCircle
    Pull To Refresh Pull Down To Refresh
    FlyRefresh Classics
    FlyRefresh ClassicsHeader
    Phoenix Taurus
    Yalantis/Phoenix Yalantis/Taurus
    BattleCity HitBlock
    FunGame/BattleCity FunGame/HitBlock
    WaveSwipe Material
    WaveSwipeRefreshLayout MaterialHeader
    StoreHouse WaterDrop
    CRefreshLayout WaterDrop

    框架

    如果你看完了效果图,或许框架的意思应该有所了解了~~SmartRefreshLayout对下拉刷新功能进行系统的拆分、组合,主要由四个部分组成:

    • RefreshLayout 下拉的基本功能,包括布局测量、滑动事件处理、参数设定等等
    • RefreshContent 对不同内容的统一封装,包括判断是否可滚动、回弹判断、智能识别
    • RefreshHeader 下拉头部的实现和显示
    • RefreshFooter 上拉底部的实现和显示

    下面是UML关系类图

    jpg_uml.jpg

    通过SmartRefreshLayout框架,你可以在一个稳定强大的下拉布局中实现自己项目需求的 Header ,不用去关心滑动事件处理,不用关心子控件的回弹和滚动边界,只需关注自己真正的项目需求Header的样子和动画。

    特点

    这时你会问:网上其他的开源下拉控件一样的可以自定义 Header 和 Footer ,SmartRefreshLayout 和它们比起来有什么优势?

    变换方式

    • Translate 平行移动 特点: 最常见,HeaderView高度不会改变,
    • Scale 拉伸形变 特点:在下拉和上弹(HeaderView高度改变)时候,会自动触发OnDraw事件
    • FixedFront 固定在前面 特点:不会上下移动,HeaderView高度不会改变
    • FixedBehind 固定在后面 特点:不会上下移动,HeaderView高度不会改变(类似微信浏览器效果)
    • Screen 全屏幕 特点:固定在前面,尺寸充满整个布局

    SmartRefreshLayout 的Header和Footer都有多种变换方式,适应不同风格的 Header 和 Footer,下面是不同变换方式Header的Demo

    FixedBehind 固定在后面Scale 拉伸形变

    Screen 全屏幕Translate 平行移动

    独立事件

    Header和Footer 可以独立的处理手指滑动事件来为动画提供操作指令,也可以使用RefreshLayout的核心接口来完成一些不寻常的操作指令。
    下面的打砖块 Header中 ,Header可以独立的使用滑动事件来为游戏挡板提供指令,并同时可以调用核心接口来通知RefreshLayout上下滚动列表


    智能

    智能是什么玩意?有什么用?智能主要体现 SmartRefreshLayout 对未知布局的自动识别上,这样可以让我们更高效的实现我们所需的功能,也可以实现一些非寻常的功能。下面通过自定义Header嵌套Layout作为内容 来解释 SmartRefreshLayout 的智能之处。

    自定义Header

    我们来看这一下这个伪代码例子:

        <SmartRefreshLayout>
            <ClassicsHeader/>
            <TextView/>
            <ClassicsFooter/>
        </SmartRefreshLayout>
    

    在Android Studio 中的预览效果图

    对比代码和我们预想的一样,那我们来对代码做一些改动,ClassicsHeader换成一个简单的TextView,看看会发生什么?

        <SmartRefreshLayout>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="100dp"
                android:gravity="center"
                android:background="#444"
                android:textColor="#fff"
                android:text="看看我会不会变成Header"/>
            <TextView/>
            <ClassicsFooter/>
        </SmartRefreshLayout>
    

    在Android Studio 中的预览效果图 和 运行效果图

    这时发现我们我们替换的 TextView 自动就变成了Header,只是它还不会动。要动起来?那么太简单啦,网上随便一搜索就一大堆的 gif 。如这里:拖拖拖 ~~垃机C4D,类似的我们还可以找到很多,又如:环游东京30天:GIF版旅行指南

    那我们就选择 环游东京30天:GIF版旅行指南 中的这张:

    image

    接着我们来改代码:

    compile 'pl.droidsonroids.gif:android-gif-drawable:1.2.3'//一个开源gif控件
    
        <SmartRefreshLayout>
            <pl.droidsonroids.gif.GifImageView
                android:layout_width="match_parent"
                android:layout_height="150dp"
                android:scaleType="centerCrop"
                android:src="@mipmap/gif_header_repast"/>
            <ListView/>
            <ClassicsFooter/>
        </SmartRefreshLayout>
    

    在 Android Studio 中的预览效果图 和 运行效果图

    哈哈!一行Java代码都不用写,就完成了一个自定义的Header

    嵌套Layout作为内容

    如果boos要求在列表的前面固定一个广告条怎么办?这好办呀,一般我们会开开心心的下下这样的代码:

    <LinearLayout
        android:orientation="vertical">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:gravity="center"
            android:text="我就是boos要求加上的广告条啦"/>
        <SmartRefreshLayout>
            <ListView/>
        </SmartRefreshLayout>
    </LinearLayout>
    

    但是在运行下拉刷新的时候,我们发现 Header是在广告条之下的,看着会别扭~,其实我们可以试试另一种方式,把广告条写到 RefreshLayout内部,看看会发生什么?

    <SmartRefreshLayout>
        <LinearLayout
            android:orientation="vertical">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="100dp"
                android:gravity="center"
                android:text="我就是boos要求加上的广告条啦"/>
            <ListView/>
        </LinearLayout>
    </SmartRefreshLayout>
    

    由于伪代码过于简单,而且运行效果过于丑陋,这里还是贴出在实际项目中的实际情况吧~

    我们注意看右边的图,仔细观察手指触摸的位置和下拉效果。可以看到在列表已经滚动到中部时,轻微下拉列表是不会触发刷新的,但是如果是触摸固定的布局,则可以触发下拉。从这里可以看出 SmartRefreshLayout 对滚动边界的判断是动态的,智能的!当然如果 SmartRefreshLayout 的智能还是不能满足你,可以通过 setListener 自己实现滚动边界的判断,更为准确!

    功能

    简单的介绍了两大特点框架和智能,接下来也说说SmartRefreshLayout还具有的其他常用功能吧~

    • 支持所有的 View(AbsListView、RecyclerView、WebView....View) 和多层嵌套的 Layout
    • 支持自定义并且已经集成了很多炫酷的 Header 和 Footer
    • 支持和ListView的同步滚动 和 RecyclerView、AppBarLayout、CoordinatorLayout 的嵌套滚动 NestedScrolling.
    • 支持在Android Studio Xml 编辑器中预览 效果
    • 支持分别在 Default(默认)、Xml、JavaCode 等三个地方设置 Header 和 Footer.
    • 支持自动刷新、自动上拉加载(自动检测列表滚动到底部,而不用手动上拉).
    • 支持通用的刷新监听器 OnRefreshListener 和更详细的滚动监听 OnMultiPurposeListener.
    • 支持自定义回弹动画的插值器,实现各种炫酷的动画效果.
    • 支持设置主题来适配任何场景的App,不会出现炫酷但很尴尬的情况.
    • 支持设置多种滑动方式来适配各种效果的Header和Footer:位置平移、尺寸拉伸、背后固定、顶层固定、全屏
    • 支持内容尺寸自适应 Content-wrap_content
    • 支持继承重写和扩展功能,内部实现没有 private 方法和字段,继承之后都可以重写覆盖
    • 支持越界回弹(Listview、RecyclerView、ScrollView、WebView...View)

    使用

    简单用例

    1.在 buld.gradle 中添加依赖

    compile 'com.android.support:appcompat-v7:25.3.1'//版本随意
    compile 'com.scwang.smartrefresh:SmartRefreshLayout:1.0.4'
    compile 'com.scwang.smartrefresh:SmartRefreshHeader:1.0.4'//没有使用特殊Header,可以不加这行
    

    2.在XML布局文件中添加 SmartRefreshLayout

    <?xml version="1.0" encoding="utf-8"?>
    <com.scwang.smartrefresh.layout.SmartRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/refreshLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:overScrollMode="never"
            android:background="#fff" />
    </com.scwang.smartrefresh.layout.SmartRefreshLayout>
    

    3.在 Activity 或者 Fragment 中添加代码

    RefreshLayout refreshLayout = (RefreshLayout)findViewById(R.id.refreshLayout);
    refreshLayout.setOnRefreshListener(new OnRefreshListener() {
        @Override
        public void onRefresh(RefreshLayout refreshlayout) {
            refreshlayout.finishRefresh(2000);
        }
    });
    refreshLayout.setOnLoadmoreListener(new OnLoadmoreListener() {
        @Override
        public void onLoadmore(RefreshLayout refreshlayout) {
            refreshlayout.finishLoadmore(2000);
        }
    });
    

    使用指定的 Header 和 Footer

    1.方法一 全局设置

    public class App extends Application {
        static {//static 代码段可以防止内存泄露
            //设置全局的Header构建器
            SmartRefreshLayout.setDefaultRefreshHeaderCreater(new DefaultRefreshHeaderCreater() {
                    @Override
                    public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) {
                        layout.setPrimaryColorsId(R.color.colorPrimary, android.R.color.white);//全局设置主题颜色
                        return new ClassicsHeader(context).setSpinnerStyle(SpinnerStyle.Translate);//指定为经典Header,默认是 贝塞尔雷达Header
                    }
                });
            //设置全局的Footer构建器
            SmartRefreshLayout.setDefaultRefreshFooterCreater(new DefaultRefreshFooterCreater() {
                    @Override
                    public RefreshFooter createRefreshFooter(Context context, RefreshLayout layout) {
                        //指定为经典Footer,默认是 BallPulseFooter
                        return new ClassicsFooter(context).setSpinnerStyle(SpinnerStyle.Translate);
                    }
                });
        }
    }
    

    注意:方法一 设置的Header和Footer的优先级是最低的,如果同时还使用了方法二、三,将会被其他方法取代

    2.方法二 XML布局文件指定

        <com.scwang.smartrefresh.layout.SmartRefreshLayout
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:id="@+id/smartLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#444444"
            app:srlPrimaryColor="#444444"
            app:srlAccentColor="@android:color/white"
            app:srlEnablePreviewInEditMode="true">
            <!--srlAccentColor srlPrimaryColor 将会改变 Header 和 Footer 的主题颜色-->
            <!--srlEnablePreviewInEditMode 可以开启和关闭预览功能-->
            <com.scwang.smartrefresh.layout.header.ClassicsHeader
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:padding="@dimen/padding_common"
                android:background="@android:color/white"
                android:text="@string/description_define_in_xml"/>
            <com.scwang.smartrefresh.layout.footer.ClassicsFooter
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
        </com.scwang.smartrefresh.layout.SmartRefreshLayout>
    

    注意:方法二 XML设置的Header和Footer的优先级是中等的,会被方法三覆盖。而且使用本方法的时候,Android Studio 会有预览效果,如下图:

    不过不用担心,只是预览效果,运行的时候只有下拉才会出现~

    3.方法三 Java代码设置

    final RefreshLayout refreshLayout = (RefreshLayout) findViewById(R.id.smartLayout);
    //设置 Header 为 Material风格
    refreshLayout.setRefreshHeader(new MaterialHeader(this).setShowBezierWave(true));
    //设置 Footer 为 球脉冲
    refreshLayout.setRefreshFooter(new BallPulseFooter(this).setSpinnerStyle(SpinnerStyle.Scale));
    
    

    相关文章

      网友评论

      • ccb0b67a541d:出来一个Leaks的文件,那是什么
      • zhang_xjm:发现一个bug,淘宝二楼的功能中,如果那张淘宝截图换成一个textView,进去后能看到二层布局背景图片。 滑动一下,背景就成白色的。
      • N城渔夫:如何实现监听方法
      • ruanyandong:谁有demo的源代码
      • ruanyandong:博主,刚开始学的android的小白,可以看下你的demo的源代码吗
      • 挽弥勒:大佬,github 上 andorid studio版本太低了把,新版本编译一堆问题
      • 青青上草:大佬,1.0.5以上是不是把自定义header的智能之处取消了。按你的文档上面写,没有效果
      • xwp:要写很多的代码控制效果,finishrefresh(true),nomoredata,loadmorefinish.enableloadmore.还有请求不到数据还要静止掉loadmore,正常又要打开,且这些代码都是重复的。楼主使用的时候有没有这些烦恼
      • 微小的沙土:怎么开始下拉 和 结束 下拉,我要点按钮 下拉
        scwang90:autoRefresh + finishRefresh
      • 猿小武:为什么每次刷新的时候,内存都直线上升呢?我用AS 的性能工具检测过,尝试下拉了好几次,内存飙到800M,log打印OPENGL memory out!!!
      • 客观开发者:支持自动刷新、自动上拉加载(自动检测列表滚动到底部,而不用手动上拉). 这怎么判断的?
        scwang90:使用速度追踪器+边界判断
      • 阿宽_袁:请问下,刷新控件中界面布局几套了多个Fragment,在界面显示的时候到偶尔某些布局悬浮在最上层导致布局混乱,是否是刷新控件重新进行了界面布局的排序啊,该怎么解决
        妙善7023:请问解决了吗,我也遇到了这个问题
      • vincent210:怎么设置加载完成后的提示语,比如没有数据了提示“无更多数据”
        scwang90:直接再 Adapter 末尾加一个 item
        就好了
        不冷大叔:怎么破的
      • 蛆宝宝:集成之后 头部卡 怎么破。。
      • 阿宽_袁:上拉加载怎么做到跟下拉刷新一样有粘性,现在上拉加载随便滑动都会加载,动画还没出来就加载了。
        阿宽_袁:@scwang90 嗯,谢谢了
        scwang90:setEnableAutoLoadmore(false) 就可以了
      • 心事重重啦啦啦啦:刷新和加载前面的那个progress怎么更换阿
        scwang90:直接设置,有对应的属性和方法
      • 莫不如哦:怎么自定义footer啊
        scwang90:和 自定义 header 一样,github 主页有 说明
      • wo叫天然呆:终于找到个看起来比较好的下拉刷新控件了android-Ultra-Pull-To-Refresh应该可以被替代掉了
      • shawnleng:学习了,感谢分享

      本文标题:Android智能下拉刷新框架-SmartRefreshLayo

      本文链接:https://www.haomeiwen.com/subject/fukchxtx.html