史上最简单的Recycleview自定义下拉刷新
来源:互联网 发布:java老版手机游戏 编辑:程序博客网 时间:2024/06/06 00:54
public class MyRecycleview extends RelativeLayout implements View.OnTouchListener { private int touchSlop;//判断为滚动的最小距离 private MarginLayoutParams headparams;//顶部布局管理器 private MarginLayoutParams bottomparams;//底部部布局管理器 private LayoutParams params, bparams;//设置布局摆放位置的容器 private View headview; //顶部布局文件 private View bottomview;//底部布局文件 private int startTop;//顶部布局初始偏移量 private int startBot;//底部布局初始偏移量 private Boolean once = true; //设置onLayout执行一次的标志位 private boolean cantopull = true;//判断当前是否可以执行下拉操作 private boolean cantopullUp = false;//判断当前是否可以执行上拉操作 private Boolean isMoving = false;//标志是否正在下拉; private RecyclerView mrecyclerView; private LinearLayoutManager mlinearlayoutmanager; private int Ydwon, Ymove, distance;//记录手指触摸及移动时相对应的Y的坐标值 private int currentMarg; //头部布局当前的偏移量 private Boolean canRefresh = false; //标志是否下拉到了刷新的位置 private RefreshListener listener; //监听回调的内部接口 private int status = 0;//当前状态 private TextView head_text, bottom_text;//顶部和底部的文字 public MyRecycleview(Context context) { this(context, null); } public MyRecycleview(Context context, AttributeSet attrs) { super(context, attrs); touchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); //拿到顶部布局 headview = LayoutInflater.from(context).inflate(R.layout.myrecycleview_headview, null, false); head_text = (TextView) headview.findViewById(R.id.pullText); //设置为屏幕水平居中 params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); params.addRule(RelativeLayout.CENTER_HORIZONTAL, TRUE); addView(headview, params); headparams = (MarginLayoutParams) headview.getLayoutParams(); bottomview = LayoutInflater.from(context).inflate(R.layout.mrecycleview_bottom, null, false); bottom_text = (TextView) bottomview.findViewById(R.id.bottom_text); bparams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); //设置为居父类布局的底部 bparams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, TRUE); addView(bottomview, bparams); bottomparams = (MarginLayoutParams) bottomview.getLayoutParams(); }
@Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); if (changed && once) { once = false; startTop = headview.getHeight(); headparams.topMargin = -startTop; headview.setLayoutParams(headparams); startBot = bottomview.getHeight(); bottomparams.bottomMargin = -startBot; bottomview.setLayoutParams(bottomparams); mrecyclerView = (RecyclerView) getChildAt(2); mrecyclerView.setOnTouchListener(this); } }//对recycleview进行事件监听 @Override public boolean onTouch(View view, MotionEvent motionEvent) { //判断是否可进行下滑 isenableToPull(); if (cantopull) { //如果可以下拉 switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: Ydwon = (int) motionEvent.getRawY(); break; case MotionEvent.ACTION_MOVE: Ymove = (int) motionEvent.getRawY(); distance = Ymove - Ydwon; if (distance > 20 && status != 1) { //满足下拉条件 currentMarg = -startTop + distance / 3;if (currentMarg > startTop) { canRefresh = true; currentMarg = startTop; status = 4;//松开即可刷新status = 2;//正在下拉状态//如果是处于下拉,或者下拉到了最底部,则需要刷新下拉头的文字信息head_text.setText("下拉加载更多");head_text.setText("松开刷新");}
//正在滑动,不允许判断是否到达顶部 isMoving = true; headparams.topMargin = currentMarg; headview.setLayoutParams(headparams); } else { return false; } break; case MotionEvent.ACTION_UP: if (canRefresh) {// 顶部布局回弹至上方 new ToprefreshTask().execute(-30); } else { //隐藏顶部布局 new HideTop().execute(-30); } //判断滑动结束,可以再次判断是否到达顶部 isMoving = false;//下拉结束 break; } //这里是底部上拉加载的模块,原理几乎和顶部下拉加载一样,就没过多实现 else if (cantopullUp) {//可以模仿着下拉刷新实现,只是下拉变成了上拉,我相信你肯定能ok的 switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: break; case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_UP: break; } } return false; } //判断是否滑到顶部,或者底部 private void isenableToPull() { mrecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { if (!recyclerView.canScrollVertically(-1)) { //滑动到了顶部可以下拉 cantopull = true; cantopullUp = false; } else if (!recyclerView.canScrollVertically(1)) { //滑动到了底部,可以上拉 cantopull = false; cantopullUp = true; } else { /** *ismoving是判断当在下拉时,列表滚动到了不是顶部的位置,这时,顶部布局就无法复原了, * 这里加个标志位,当手指还在拖拽下拉条时,返回当前是否到达顶部,当手指松开屏幕时,ismoving * 变为FALSE,回到初始状态,可以判断是否到达顶部了; */ if (!isMoving) { cantopull = false; cantopullUp = false; } } } }); }//头部下拉到进行刷新时调用class ToprefreshTask extends AsyncTask<Integer, Integer, Integer> { @Override protected Integer doInBackground(Integer... integers) { int topmarg = headparams.topMargin; while (true) { topmarg = topmarg + integers[0]; ; //当回到顶部时,跳出 if (topmarg <= 0) { topmarg = 0; break; } publishProgress(topmarg); try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } } publishProgress(0); status = 1; if (listener != null) { listener.Refresh(); } return null; } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); headparams.topMargin = values[0]; headview.setLayoutParams(headparams); }}//隐藏头部的布局文件class HideTop extends AsyncTask<Integer, Integer, Integer> { @Override protected Integer doInBackground(Integer... integers) { int topmarg = headparams.topMargin; while (true) { topmarg = topmarg + integers[0]; //当回到顶部时,跳出 if (topmarg <= -startTop) { topmarg = -startTop; break; } publishProgress(topmarg); try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } } publishProgress(-startTop); return topmarg; } @Override protected void onPostExecute(Integer integer) { super.onPostExecute(integer); headparams.topMargin = integer; headview.setLayoutParams(headparams); canRefresh = false; } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); headparams.topMargin = values[0]; headview.setLayoutParams(headparams); }}//设置外部调用的的方法 public void setRefreshListener(RefreshListener listener) { this.listener = listener; } //设置外部的监听回调接口 public interface RefreshListener { void Refresh(); } public void FinishRefresh() { new HideTop().execute(-30); status = 3;//下拉刷新结束状态; }}//上边,需要自定义一个顶部布局文件<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="100dp" > <ProgressBar android:layout_width="wrap_content" android:layout_height="50dp" android:layout_toRightOf="@+id/pullText" android:background="@drawable/head_backview"/> <TextView android:layout_centerVertical="true" android:id="@+id/pullText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="下拉刷新"/></RelativeLayout>//最后在主布局里面添加该自定义的view
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <com.example.test.demo.view.MyRecycleview android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/myrecycleview"> <android.support.v7.widget.RecyclerView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/recyclew"/> </com.example.test.demo.view.MyRecycleview></LinearLayout>//在代码中进行初始化,和下拉监听myRecycleview.setRefreshListener(new MyRecycleview.RefreshListener() { @Override public void Refresh() {//这里用个延时,模拟向服务器请求数据 try { Thread.sleep(1500); } catch (InterruptedException e) { e.printStackTrace(); } myRecycleview.FinishRefresh(); } });}
0 0
- 史上最简单的Recycleview自定义下拉刷新
- 自定义下拉刷新和上拉加载的recycleview
- 【实训】自定义上拉加载下拉刷新的RecycleView
- RecycleView的上啦加载下拉刷新
- SwipeRefreshLayout+RecycleView下拉刷新
- RecycleView+SwipeToLoadLayout+Fresco的自定义刷新加载
- RecycleView + SwipeRefreshLayout 实现下拉刷新
- 提供一个简单可以自定义的下拉刷新实现
- RecycleView的多条目展示及原生下拉的刷新
- 轻松实现RecycleView的下拉刷新、加载更多
- Recycleview下拉刷新,上拉加载的思路
- Recycleview的上拉刷新与下拉加载
- 下拉刷新 上拉加载的 ListView RecycleView ScorllView
- 自定义RecycleView实现下拉刷新和上拉刷新(源码注释)
- 自定义ExpandableListView下拉刷新功能简单实现(这里主要说自定义可下拉的功能)
- RecycleView下拉刷新控件的封装(包括下拉刷新和加载更多 )
- 自定义下拉刷新的listview
- 自定义的下拉刷新SwipeRefreshLayout
- 三极管的三个工作状态
- 题目1194:八进制
- 给已经存在的项目添加git
- 谷歌浏览器禁用缓存
- 数据库连接池与com.mysql.jdbc.exceptions.jdbc4.CommunicationsException异常
- 史上最简单的Recycleview自定义下拉刷新
- es(elasticsearch)游标(查询)的理解
- 封面与目录不要页码,从第三页正文开始要页码的设置方法
- 题目1195:最长&最短文本
- 开发服务端程序,在存在并发请求场景下,需要考虑一些常规事项简单梳理和总结
- 数据库大小写敏感问题
- woowj 首页推荐商品
- luogu P1015 回文数
- 深度学习框架汇总