美文网首页Android DevAndroid技术知识Android Dev
Android 开源之StickyHeaderListView

Android 开源之StickyHeaderListView

作者: 孙福生微博 | 来源:发表于2016-04-26 12:10 被阅读20601次

    StickyHeaderListView 是基于实际需求做出的灵活可定制的UI功能,具体实现功能如下:
    一、支持无限循环的广告位。
    二、高度可动态配置的Header2和Header3(使用GridView实现)。
    三、主要功能:分类、排序和筛选布局滑动到顶部后吸附、悬停。
    四、自定义FilterView筛选控件,支持动画显示与动画隐藏。
    五、支持标题栏背景颜色渐变、字体颜色渐变。
    六、数据不足一屏动态添加空数据占位。
    七、数据为空时,ListView加载暂无数据视图。
    八、思路清晰、界面优美,添加ripple点击效果。
    九、支持下拉刷新和上拉加载更多功能。

    动态效果图:

    stickyheader.gif stickyheader2.gif

    GitHub开源地址

    APK下载地址

    实现思路

    StickyHeaderListView 主要是通过 ListView 添加头部实现,将复杂的头部分解为若干部分,如下图:Header 1(广告位)、Header 2(频道位)、Header 3(运营位)、Header 4(分割线) 和 Header 5(筛选头部),这样各个Header部分的UI和逻辑可以单独拿出去处理,具体可以参考我的 开源代码

    StickyHeaderListView_sumary.png

    Header 1: 它的高度影响标题栏的颜色渐变。

    Header 2: 使用GridView实现,自定义FixedGridView,高度不受ListView的影响,一行显示几个自己可以根据需求设置。

    Header 3: 和Header 2一样的实现方式,要注意的地方就是分割线的设置,我实现的思路是设置GridView的背景颜色的分割线的颜色,再设置如下的四个属性:paddingTop、paddingBottom、horizontalSpacing、verticalSpacing为1px,这样分割线就均等了。

    android:background="@color/font_black_5"
    android:paddingTop="1px"
    android:paddingBottom="1px"
    android:horizontalSpacing="1px"
    android:verticalSpacing="1px"
    

    Header 4: 这个头部布局是需求上的,UI加上整体更加好看,为什么我要单独拿出来,主要考虑到以下的原因:如果让Header 5达到吸附悬停的效果,需要知道Header 5到顶部的距离,如果把分割线加到Header 5上,那在移动的时候还需要减去这个高度;而如果加到Header 3上,Header 3是服务器动态配置的,如果没有Header 3的头部怎么办,那就加到Header 2上等,这样逻辑就比较麻烦,干脆我直接单独拿出来,作为一个头部布局动态添加。

    Header 5: 这个筛选头部是个假的布局,主要处理未吸附悬停时的点击事件,点击之后滑动到顶部这时顶部的隐藏的筛选布局显示出来达到吸附悬停的效果。同时我将这个筛选布局定义一个 FilterView,将分类、排序和筛选的UI处理和逻辑封装起来,方便其它页面的二次使用。

    还有两点需要特别注意:

    一、如果数据不满一屏,比如就一条数据,那点击筛选它是没办法滑动到顶部的,因为她的高度不够,我的解决方法是添加若干个空数据,空数据的size是根据实际一屏要显示的个数减去现在的个数,这样可以达到整体可以滑动的高度,参考 TravelingAdapter 文件。

    二、如果数据为空时并且我还需要无数据的占位图,如果在 ListView 底部加上无数据的布局这样的效果是不好的,所以我还在这个Adapter上做文章,让它加载一个无数据的视图布局,同样参考 TravelingAdapter 文件,每一个Item的高度: height = 屏幕的高度 - 标题栏高度 - 筛选View高度,这样设置一个这样的高度的Adapter,再 notifyDataSetChanged() 一下,整体的视图不会变化,无数据的占位图也自然而然的显示了。

    最后

    具体实现代码移步 GitHub,下载 APK 体验,感谢你的关注,欢迎star,希望对你有帮助,如遇到问题请联系我,最后再贴几张截图方便你查看。

    滑动到一半时标题栏渐变

    StickyHeaderListView2.png

    滑动到顶部,FilterView 吸附悬停

    StickyHeaderListView3.png

    FilterView 动画显示与隐藏

    StickyHeaderListView4.png

    数据为空时的占位图

    StickyHeaderListView5.png

    关于我

    个人邮箱:sfsheng0322@126.com
    GitHub主页
    简书主页
    个人博客
    新浪微博

    相关文章

      网友评论

      • 5c0f6aeb18ac:这个项目可以直接被引用吗?
      • 彭業:我想问下博主,我悬停后的控件为什么没有点击事件了
      • andev009:发现一个奇怪的问题,当下拉到筛选布局下面的ListView后,为什么bannerViewTopMargin,就是bannerView的getTop()就不变了呢?继续下拉ListView,getTop()值不是应该继续变化啊?请教
      • Hideonbush_Hide:学习一下,先点赞
      • longzekai:广告位的点击事件如何处理?
      • 126a74d7d320:把listview改成recycleview吧
      • Jinbeen:请问支持RecyclerView 吗?
        孙福生微博: @Jingbin_ 不支持的
      • 逐鹿者不见山:放入fragment中,部分机型在切换不同fragment的时候,item点击无效,例如华为P10 plus
      • eef446193fa7:筛选出来的内容只有一条的话,listView上拉加载完成的时候listView会变成空白页。
      • 6f0a276f06d0:如果这套界面放在fragment中 没有什么问题吗?
        孙福生微博: @谢肇伟 没有
      • 706ffab8fe0f:大神,这个能够改成新浪微博客户端发现页的页面功能呢,求指教,谢谢您
      • 3d2004e7f969:你的一屏幕只显示8条数据怎么做到的呢
      • 1412c5043b09:不知道顶部的ViewPager的点击事件好加不
      • c732b766c97c:fork一波
      • 9581f512782e:楼主为什么不用recyclerview实现呢?可以试一下,现在基本都不用listview了,正好也遇到一个类似的需求
      • 跃跃2017:HeaderBannerView里面的dealWithTheView方法里面这段代码
        if (bannerCount == 2) {
        list.addAll(list);
        }
        是为了修复了viewpager里面只有两条数据时左右滑动出现部分白屏的问题吗?
        孙福生微博: @跃跃2017 是的
      • 26625f54646c:非常赞,找了好久没找到这么完善的复杂布局,希望多多分享类似的demo
      • 布衣美漂:您好,请问APK下载了之后怎么用在我的android app上?
      • 斑马搬码:用CoordinatorLayout能实现吗?
      • b8194c36f87b:要是把项目上传到 maven 库 就更好啦。。
      • b8194c36f87b:可以的 star 一波
      • 旧人旧城旧心:真心不错!apk不能直接用,我下载的源码,运行了一下就OK了!!!赞一个!!!!!
        孙福生微博: @旧人旧城旧心 谢谢谬赞
      • 3ee6e9ef0293:下拉刷新,headview的数据发生变化,你如何刷新headview的数据呢,我刷新后重设了headview的数据的时候出现了空指针
        孙福生微博: @没有资本装逼 加油
        可可源:@txfyteen 我也在想,决定改改它
      • 0d3928a9f2ff:请问怎样才能把底下的listview改成gridview???
      • 29778cb33978:写的真不错,给群主一个赞。
        孙福生微博:@需要提升的我 谢谢,希望能帮到你
      • 呃哈哈:我下载apk要么不能用直接崩,要么就是小游戏
      • 咸鱼而已:没想到能在这看到你。之前在微博见过你这个项目,还搞下来看了一下
        孙福生微博: @有一种思念望眼欲穿 你所到之处就有我的身影,哈哈
      • LooperJing:不错
        孙福生微博: @醉风景 谢谢
      • 尸情化异:bug+1,你把筛选选到西班牙,然后把listview往上推,然后放手,你会发现,悬浮的在toolbar上的dropdownmenu和listview上面的dropdownmenu都出现了
        孙福生微博: @尸情化异 希望可以帮到你
        尸情化异: @孙福生微博 不错哦~希望可以用到项目里面
        孙福生微博: @尸情化异 好神奇,我看看
      • fe2a5bcdf6ea:错了 是header1 2 3里面的
      • fe2a5bcdf6ea:大神 弱弱的问下 如何获取heard1heard2heard3 里面的点击事件啊
        Ivor0057:@蹦蹦跳跳真可爱 在LayoutInflater后,可以对具体的子控件监听呀
      • logan676:请问如何高亮“ListView头部展示的假的筛选视图点击”呢,比如我的筛选栏有三个栏目,“默认排序”,“价格排序”,“筛选”。如果用户选择了“价格排序”栏目中的某一个筛选项之后,比如选择“价格从高到低”之后,需要高亮它。在FilterView中可以正确的高亮,但是一滑动列表,高亮效果就消失了,因为显示的是“假的筛选视图”,那请问如何高亮“假的筛选视图”呢?
        logan676:@孙福生微博 是可以处理,不过不知道我按照下面这样处理是否合理。由于有两个“筛选视图”,而筛选条件是维护在各个FilterView内部的,导致有两份筛选条件。因为数据不一致,所以无法设置悬停和滑动的状态相同的高亮效果。只维护一份筛选条件可以解决这种不一致,但是需要fvTopFilter(FilterView)把筛选条件传递给headerFilterViewView(假的筛选视图)。这样处理是不是不太好?
        孙福生微博: @logan676 在FilterView中都可以处理
      • logan676:还有就是"设置运营数据"的时候能否不适用gridview而是支持一个简单的FrameLayout或者LineaLayot布局呢?
      • logan676:"设置运营数据"的时候,例子中使用的是静态数据,请问是否支持加载动态数据呢,支持的话应该如何做呢?现在做的项目有一个需求是在实现悬浮的基础上,要动态加载网络数据,但是页面加载完毕之后网络数据才返回,这时候才能设置“运营数据”。请问这是否可行呢?
        孙福生微博: @logan676 这肯定的,所以要开始全部add上,先隐藏
        logan676:@孙福生微博 "数据回来后显示"我调用的是 headerOperationViewView.fillView(operationList, smoothListView);
        但是结果导致,布局乱掉了。headerOperationViewView跑到了上面去。
        孙福生微博: @logan676 你可以开始就把头部都添加进去,先隐藏,数据回来后显示
      • 83461ab8a324:能不能封装成一个简单可用的控件?
        孙福生微博: @83461ab8a324 封装可能用起来更加方便,但不适合变化的项目需求。
      • bimromatic:我想拜师
        孙福生微博: @1b25563464b9 加我微信可以交流交流,微信号: sfs321
      • bimromatic:很开心看到你的这边讲解,我已被PullToRefreshListView的实现伤透心了
      • 风逝葬:大神吊吊的
        风逝葬:@孙福生微博 我把那个filterView放到adt中 运行不了 只能在as中可以
        孙福生微博: @风逝葬 呵呵,低调
      • 奔跑的笨鸟:能安装无法运行,酷派4.4系统
        孙福生微博: @feimeng0530 运行就崩溃吗?我看看
      • C_zx:APK有问题啊 我的三星S5启动直接崩了
        孙福生微博: @CoderLeo 我上传了新版本,你试试吧
        下载地址: http://fir.im/StickyListView
        孙福生微博: @CoderLeo 好的,我看看,我的手机上可以,我找个手机看看哈
      • 831c5825cf50:楼主,我是小米3.安装直接报错。
        孙福生微博: @段字一阵风 明天我看看哈,要不你运行下看看哪出问题
      • 攻城狮Song:很厉害 。谢谢分享。 楼主有空的时候可以试试 大姨妈app 主界面的日子选择控件编写。 小弟写的达不到那种效果。
        孙福生微博: @攻城狮Song 好的,我调研下
      • aee52c6e3ba2:学习,学习,已提issue :smile:
        孙福生微博: @张益达不加_V 谢谢,我看看问题
      • 7c93775cba9c:一直在想双吸顶效果的实现,深受启发。谢谢。暂时思路是PinnedSectionListView结合你的这种吸顶思路。还有一种思路是不用PinnedSectionListView,直接使用你的这种吸顶思路的实现方式。
        孙福生微博: @robertj 拿去不谢,呵呵
      • 小王泽哥:孙总,我想拜师
        孙福生微博: @小王泽哥 哈哈,收下
      • 阿木小巫X:怒赞
        孙福生微博: @阿木小巫X 哈哈
      • 王洪贺:试试recyclerview和cordinatorlayout和collapseappbarlayout实现吧,现在基本不用listview和gridview了
        9177825bbe22:用cordinatorlayout和collapseappbarlayout实现有bug,顶部滑动没有fling效果,而且下面的列表滑动时有跳动问题
        new一个:说实在想要达到示例这么优美,用cordinatorlayout和collapseappbarlayout很难
        孙福生微博: @王洪贺 好的
      • faf5b17698ae:请问一下,那个header5是怎么做的?
        孙福生微博: @Nastasia 你的手机什么型号,手机版本多少
        faf5b17698ae:@孙福生微博 我下载了apk打开不了,闪退,是不是不兼容?去哪里看你的源代码?不好意思,刚接触不懂
        孙福生微博: @Nastasia 啊,你先看FilterView吧,相信你能看明白
      • 205蚁:赞一个, 我这几天也有想法弄这个东西,感谢分享
      • 伐冰:华为手机和Genymotion模拟器都打不开。。。
        7326856406c2:为什么我的电脑装不上genymotion?
        7c93775cba9c:@孙福生微博 打包所用build tool版本太高了,小于2.0可以。classpath 'com.android.tools.build:gradle:1.3.0'
        孙福生微博: @伐冰 可以把log信息发出来吗
      • kaikaifly:下拉刷新SmoothListView是参考自哪个项目呢
        孙福生微博: @kaikaifly XListView
      • 034a77616c2e:忍不住赞一个
        孙福生微博: @034a77616c2e 谢谢
      • gzfgeh:我用的最新的二维码,还是不能运行,小米手机
        孙福生微博: @gzfgeh 我的也是小米手机,手头手机型号不多,麻烦你运行下吧
      • c83a487548eb:必须赞
        孙福生微博: @宅男的咆哮 没有,看来不满足你的需求啦,不过有个开源项目可以
        c83a487548eb:@孙福生微博 有没有试过下面是可以滑动的viewpage,其他功能和你这个一样全都有的
        孙福生微博: @宅男的咆哮 谢谢
      • 606fd5f5448c:apk安装后打不开
        606fd5f5448c:@孙福生微博 好的
        孙福生微博: @Andrman 你在重新下载一下,我修复了这个问题
      • coco猫:下路一个apk ,感觉很体验很流畅,赞
        孙福生微博: @coco猫 谢谢
      • wavever:赞
        孙福生微博: @反阿怪 确认是下载最新的包吗?一会我再看看
        139f1c2288d3:@孙福生微博 滑动一半的时候 点击筛选没反应 应该点到假布局上去了
        孙福生微博: @wavever 谢谢

      本文标题:Android 开源之StickyHeaderListView

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