一、前言

最近有一个需求就是上拉、下拉整体刷新一页数据,并且将下一页数据整体划出显示,上一页数据则消失。这个类似于选股宝的头条选股的效果,先上图。

二、实现心路历程

拿到这个需求,我就想,我靠,没搞过啊,这个怎么弄!仔细看,这好像就是上拉刷新、下拉加载呀,怎么实现?套两层recycleView?里面负责显示,外面一层负责动画?添加header 和 footer?然后增加动画,还有阻尼效果?不行不行,实现时间太长,不允许!找找网上有没有实现好的开源代码,然后:“仿选股宝选股头条上拉加载”等等,都没有。那只能自己实现了,然后自己再细看这玩意,越看越像之前ListView时代的PullToRefresh,然后我就想,找一个这样的上下组件,然后这种入场方式就自己实现:先上拉,数据出来之后,记录新加载的第一条数据,然后从该条开始,向上或者向下移动。最后和大佬说这个方案的时候,他给我提意见:你这样就弄得整个recycleView的逻辑很复杂,你还不如利用Fragment显示,让它处理数据显示,动画,进出场,recycleView只负责列表显示。瞬间茅塞顿开。

三、上代码

上下拉加载,我就自己不造轮子了,有很多大牛写的很好,找了几个,最终选中了https://www.cnblogs.com/zhujiabin/p/7425535.html 这个,我对他的代码做了小小的改动,增加下拉加载时,没有数据,显示到顶了,类似于上拉没有数据的那种效果,具体修改思路按照代码中底部加载完成字段isMore 增加isPreviousData字段控制,代码就不贴了,比较简单,稍微改下就行。

3.1具体使用

3.1.1 用一个Activity承接Fragment

PullRefreshActivity.java

public class PullRefreshActivity extends AppCompatActivity {@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_pull_refresh);BaseFragment fragment = new BaseFragment();BaseFragment fragment2 = new BaseFragment();getSupportFragmentManager().beginTransaction().replace(R.id.fl_root, PullRefreshFragment.newInstance(it)).setCustomAnimations(R.anim.fragment_top_in, R.anim.fragment_bottom_out, R.anim.fragment_bottom_in, R.anim.fragment_top_out).commit();}
}

其XML文件很简单,就一个FrameLayout,这里就不贴出了,说明一下,这个代码仅用于demo,具体项目中,这Activity得加载一次数据,在数据加载成功回调中切换Fragment,然后在Fragment中,Fragment代码如下:
PullRefreshFragment.kt

class PullRefreshFragment: Fragment() {private var list: PullRefreshRecyclerView? = nullprivate var pageNum: Int = 0private var adapter: MyAdapter? = nullprivate val data = ArrayList<String>()override fun onCreateView(inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?): View? {val view = inflater.inflate(R.layout.fragment_six, container, false)list = view.findViewById<PullRefreshRecyclerView>(R.id.list)PullRefreshUtil.setRefresh(list as PullRefreshView, true, true)adapter = MyAdapter(activity, data)list?.setLayoutManager(LinearLayoutManager(activity))list?.setAdapter(adapter)loadData()list?.setOnPullDownRefreshListener {list?.isPreviousData(true)pageNum = 1loadData()list?.refreshFinish()}list?.setOnPullUpRefreshListener {pageNum++list?.isMore(true)loadData()list?.refreshFinish()}
list?.setOnHeadStateListener(object : PullRefreshView.OnHeadStateListener{override fun onRetractHead(head: View?) {activity?.supportFragmentManager?.beginTransaction()?..setCustomAnimations(R.anim.fragment_top_in, R.anim.fragment_bottom_out, R.anim.fragment_bottom_in, R.anim.fragment_top_out)?.replace(R.id.fl_root, PullRefreshFragment(), TAG2)?.commit()(head as HeadView).onRetractHead(head)}override fun onRefreshHead(head: View?) {(head as HeadView).onRefreshHead(head)}override fun onScrollChange(head: View?, scrollOffset: Int, scrollRatio: Int) {(head as HeadView).onScrollChange(head, scrollOffset, scrollRatio)}override fun onNotMore(head: View?) {(head as HeadView).onNotMore(head)}override fun onHasMore(head: View?) {(head as HeadView).onHasMore(head)}})//以下两个监听,为了切换Fragment,实际开发中我们不需要这两个监听,我们只要在数据加载成功回调中处理即可 list?.setOnTailStateListener(object : PullRefreshView.OnTailStateListener{override fun onScrollChange(tail: View?, scrollOffset: Int, scrollRatio: Int) {(tail as TailView).onScrollChange(tail, scrollOffset, scrollRatio)}override fun onRefreshTail(tail: View?) {(tail as TailView).onRefreshTail(tail)}override fun onRetractTail(tail: View?) {activity?.supportFragmentManager?.beginTransaction()?..setCustomAnimations(R.anim.fragment_top_in, R.anim.fragment_bottom_out, R.anim.fragment_bottom_in, R.anim.fragment_top_out)?.replace(R.id.fl_root, PullRefreshFragment())?.commit()(tail as TailView).onRetractTail(tail)}override fun onNotMore(tail: View?) {(tail as TailView).onNotMore(tail)}override fun onHasMore(tail: View?) {(tail as TailView).onHasMore(tail)}})return view}private fun loadData() {for (i in 0..14) {data.add(i.toString() + "")}adapter?.setData(data)adapter?.notifyDataSetChanged()}var mOnLoadSuccess: OnLoadSuccess? = nullfun setOnLoadSucess(onLoadSuccess: OnLoadSuccess) {this.mOnLoadSuccess = onLoadSuccess}interface OnLoadSuccess {fun loadSuccess()}
}

MyAdapter.java

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {private List<String> mData;private Context mContext;public MyAdapter(Context context, ArrayList<String> dataList) {this.mContext = context;this.mData = dataList;}public void setData(List<String> data) {this.mData = data;}@Overridepublic int getItemCount() {return mData.size();}@Overridepublic void onBindViewHolder(@NonNull ViewHolder holder, int position) {holder.tv.setText(mData.get(position));}@NonNull@Overridepublic ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(mContext).inflate(R.layout.item_adapter, parent, false);return new ViewHolder(view);}public class ViewHolder extends RecyclerView.ViewHolder {public TextView tv;public ViewHolder(View itemView) {super(itemView);tv = itemView.findViewById(R.id.tv);}}
}

其中item_adapter.xml文件很简单,只有一个TextView,这里就不贴出来了,另外Fragment进出场的四个动画如下:
fragment_bottom_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"><translateandroid:fromYDelta="100%p"android:toYDelta="0%p"android:duration="300"/><alphaandroid:fromAlpha="0.5"android:toAlpha="1.0"android:duration="300"/>
</set>

fragment_top_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"><translateandroid:fromYDelta="0%p"android:toYDelta="-100%p"android:duration="300"/><alphaandroid:fromAlpha="1.0"android:toAlpha="0.5"android:duration="300"/>
</set>

fragment_top_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"><translateandroid:fromYDelta="-100%p"android:toYDelta="0%p"android:duration="300"/><alphaandroid:fromAlpha="0.5"android:toAlpha="1.0"android:duration="300"/>
</set>

fragment_bottom_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"><translateandroid:fromYDelta="0%p"android:toYDelta="100%p"android:duration="300"/><alphaandroid:fromAlpha="1.0"android:toAlpha="0.5"android:duration="300"/>
</set>

具体效果如下:

仿选股宝选个头条上下拉加载一页的功能相关推荐

  1. uniapp弹出框_uniApp上拉刷新,下拉加载,以及筛选功能

    uniApp插件市场有很多友好的插件,今天举一个例子 如上图所示,实现上拉刷新,下来加载,右上角点击弹出筛选框,只需要在插件市场搜索刷新 选择你想要的效果(也可以下载后自己改动效果) 点击导入插件,会 ...

  2. Android_ListView上拉加载更多(ListView分页功能)

    先上效果图 加载完数据 首先定义一个底部正在加载的布局footer_layout.xml <?xml version="1.0" encoding="utf-8&q ...

  3. Android RecyclerView(八)设置自定义 下拉刷新 与 上拉加载数据

    Android RecyclerView(八)设置下拉刷新 与 上拉加载数据 GitHub 项目源码 CSDN 博客说明 智慧安卓App 文章分析 下拉刷新效果 上拉加载数据效果 1 xml布局文件中 ...

  4. ListView上拉加载和下拉刷新多种实现方式

    ListView上拉加载和下拉刷新多种实现方式 该篇为ListView下拉刷新和上拉加载实现的各种方法大合集.可能在具体的细节逻辑上处理不太到位,但基本上完成逻辑的实现.细节方面,个人可以根据自己的需 ...

  5. 仿头条新闻app,实现下拉刷新,上拉加载分页

    ---恢复内容开始--- 环境appcan appcan.ready(function() {page = 1;type = 0;searchDate = getNowTime();highSearc ...

  6. ASP.NET仿新浪微博下拉加载更多数据瀑布流效果

    闲来无事,琢磨着写点东西.貌似页面下拉加载数据,瀑布流的效果很火,各个网站都能见到各式各样的展示效果,原理大同小异.于是乎,决定自己写一写这个效果,希望能给比我还菜的菜鸟们一点参考价值.       ...

  7. iOS高仿微信、仪表盘、图片标注图片滤镜、高斯模糊、上拉加载、下拉刷新等源码

    iOS精选源码 Swift-图片画框标注 Swift版的上拉加载, 下拉刷新控件(一句话集成, 超级易用) iOS tabbar上的提示框 Swift图片浏览器,经过一年多维护,已基本稳定 图片滤镜 ...

  8. iOS高仿微信、仪表盘、图片标注图片滤镜、高斯模糊、上拉加载、下拉刷新等源码...

    iOS精选源码 Swift-图片画框标注 Swift版的上拉加载, 下拉刷新控件(一句话集成, 超级易用) iOS tabbar上的提示框 Swift图片浏览器,经过一年多维护,已基本稳定 图片滤镜 ...

  9. listview下拉刷新上拉加载扩展(三)-仿最新版美团外卖

    本篇是基于上篇listview下拉刷新上拉加载扩展(二)-仿美团外卖改造而来,主要调整了headview的布局,并加了两个背景动画,看似高大上,其实很简单: as源码地址:http://downloa ...

最新文章

  1. 布Sendmail之网,安全则不漏(上)
  2. Delphi Code Editor 之 编辑器选项
  3. 编译原理练习题(第三章)
  4. opencv画框返回坐标 python_python opencv鼠标事件实现画框圈定目标获取坐标信息
  5. 全球及中国益生菌市场应用发展与投资前景调研报告2022版
  6. 云服务器建站原理_云服务器cvm与建站主机之间的区别
  7. LeetCode MySQL 1587. 银行账户概要 II
  8. Spring 整合junit
  9. 一步一步教你玩转.NET Framework的配置文件app.config (转载)
  10. Docker安装迅雷下载工具实现远程下载
  11. 电子政务工程建设项目可行性研究报告编制要求
  12. 华为2018届校园招聘笔试题目以及相应代码分享 软件开发岗位
  13. 解决vscode的任务栏白色图标的问题
  14. 京东2022双11预售期,商家该做些什么?
  15. 中值滤波Median filtering
  16. C语言三个数相乘怎么写,编程怎么写乘法
  17. 光纤快速连接器如何安装使用?与冷接子有何区别?
  18. linux mint卸载桌面环境,在Ubuntu系统中安装最新Cinnamon桌面环境,包括启用及卸载...
  19. 数据中台架构与技术选型
  20. 下载Nexus老版本war包

热门文章

  1. 【艾琪出品】《计算机应用基础》【试题汇总10】
  2. 哈工大计算机系统大作业:程序人生-Hello’s P2P
  3. jQuery源码分析系列目录
  4. 何为ISM频段?ISM频段主要频率有哪些?
  5. R语言独立样本的 t 检验
  6. 组装手机DIY时代或将到来
  7. 网易互娱 实习生招聘 内推
  8. 看我如何破解一台自动售货机
  9. 灰度拉伸python_对比度拉伸(一些基本的灰度变换函数)基本原理及Python实现
  10. google 语音识别 VS 百度语音识别