Android RecyclerView(八)设置自定义 下拉刷新 与 上拉加载数据
来源:互联网 发布:梦天堂软件 编辑:程序博客网 时间:2024/06/06 02:11
Android RecyclerView(八)设置下拉刷新 与 上拉加载数据
GitHub 项目源码
CSDN 博客说明
智慧安卓App 文章分析
下拉刷新效果
上拉加载数据效果
1 xml布局文件中
<FrameLayout android:layout_width = "match_parent" android:layout_height = "match_parent" > <!--背景--> <LinearLayout style = "@style/style_bg_ll" > <TextView style = "@style/style_bg_tv" android:text = "智慧安卓" /> <TextView style = "@style/style_bg_tv_c1" android:text = "网址 www.studyyoun.com" /> <TextView style = "@style/style_bg_tv_c1" android:text = "\@2017 晋ICP备17005075号-1" /> </LinearLayout > <!--数据列表--> <android.support.v7.widget.RecyclerView android:id = "@+id/rv_list" android:layout_width = "match_parent" android:layout_height = "match_parent" android:background = "#fcfcfc" android:visibility = "visible" /> <!--表层刷新显示布局--> <LinearLayout android:id = "@+id/ll_pull_refresh_main" style = "@style/style_refresh_ll" android:visibility = "visible" > <ProgressBar android:layout_width = "30dp" android:layout_height = "30dp" /> <TextView android:id = "@+id/tv_pull_refesh" style="@style/style_refresh_tv" android:text = "下拉刷新" /> </LinearLayout > </FrameLayout >
其实在这里就是使用了三层布局
1.1 背景
1.2 显示列表数据控件 RecyclerView
1.3 显示刷新布局
2 设置 RecyclerView 显示数据
2.1 初始化数据设置
//刷新布局的高度 dpprivate int mPullRefreshDefault=62;//刷新布局的高度 px 会根据屏幕密度来进行计算private int mPullRefshLayoutHeight;private RecyclerView mRecyclerView;//下拉刷新显示的布局private LinearLayout mPullRefshLayout;//下拉刷新中显示的文字提示private TextView mPullRefTextView;//对应的布局管理者private LinearLayoutManager mLinearLayoutManager;//存储数据的集合private List<String> mStringList = new ArrayList<>();
//刷新的布局mPullRefshLayout = (LinearLayout) findViewById(R.id.ll_pull_refresh_main);//刷新的提示文字mPullRefTextView = (TextView) findViewById(R.id.tv_pull_refesh);//列表数据mRecyclerView = (RecyclerView) findViewById(R.id.rv_list);
//获取当前的屏幕密度数据DisplayMetrics displayMetrics = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);//获取当前的像素缩放比例float scaledDensity = displayMetrics.scaledDensity;//刷新布局文件的高度 mPullRefreshDefault 指定的是 62dp,在这里转换计算成实际的pxmPullRefshLayoutHeight = (int) (mPullRefreshDefault * scaledDensity);
//当视图绘制完成时将显示刷新的布局文件移出mPullRefshLayout.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout () { //将刷新的布局文件移出到屏幕外 //mPullRefshLayoutHeight 也可以使用mPullRefshLayout.getHeight()替换 mPullRefshLayout.layout(0, -mPullRefshLayoutHeight, mPullRefshLayout.getWidth(), 0); }});
//初始化模拟数据for (int i = 0; i < 16; i++) { mStringList.add("test " + i);}//设置布局样式mLinearLayoutManager = new LinearLayoutManager(this);//设置方向mLinearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);//关联RecyclerViewmRecyclerView.setLayoutManager(mLinearLayoutManager);//设置分割线mRecyclerView.addItemDecoration(new DividerItemDecoration( this, DividerItemDecoration.VERTICAL));//关联AdaptermRecyclerView.setAdapter(mViewHolderAdapter);//设置滑动监听事件mRecyclerView.setOnScrollListener(mOnScrollListener);//设置触摸监听事件mRecyclerView.setOnTouchListener(mOnTouchListener);
2.2 Adapter 与 ViewHolder的设置
2.2.1 显示正常数据的条目布局 item.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android = "http://schemas.android.com/apk/res/android" android:layout_width = "match_parent" android:layout_height = "match_parent" > <LinearLayout android:layout_width = "match_parent" android:layout_height = "wrap_content" android:background = "#fff" android:orientation = "vertical" > <TextView android:id = "@+id/tv_item_text" android:layout_width = "match_parent" android:layout_height = "80dp" android:text="测试数据" android:background = "#acd972" android:gravity = "center" /> </LinearLayout ></RelativeLayout >
2.2.2 显示刷新数据的条目布局 refresh_view_footer.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android = "http://schemas.android.com/apk/res/android" android:layout_width = "match_parent" android:layout_height = "match_parent" android:background = "#232323" android:orientation = "vertical" > <LinearLayout android:layout_width = "match_parent" android:layout_height = "match_parent" android:gravity = "center" android:orientation = "horizontal" > <ProgressBar android:layout_width = "30dp" android:layout_height = "30dp" /> <TextView android:id = "@+id/tv_loading_more" android:layout_width = "wrap_content" android:layout_height = "45dp" android:layout_marginLeft = "18dp" android:gravity = "center" android:text = "正在加载更多数据" android:textColor = "#fff" android:textSize = "14sp" /> </LinearLayout ></RelativeLayout >
2.2.3 数据设置
需要注意的是,在这里,设置的是当显示的数据条目大于10条时,才启动上拉加载更多数据
这是处理当数据为少量时,下拉刷新与上拉加载更多冲突的一种方式
private RecyclerView.Adapter<ViewHolder> mViewHolderAdapter = new RecyclerView.Adapter<ViewHolder>() { @Override public ViewHolder onCreateViewHolder (ViewGroup parent, int viewType) { if (viewType == 0) { //加载条目布局文件 View view = View.inflate(HomeActivity.this, R.layout.item, null); //创建ViewHolder CustomViewHolder customViewHolder = new CustomViewHolder(view); return customViewHolder; } else { //最后一个条目设置刷新布局显示 View view = View.inflate(HomeActivity.this, R.layout.refresh_view_footer, null); //创建ViewHolder UpLoadViewHolder customViewHolder = new UpLoadViewHolder(view); return customViewHolder; } } @Override public void onBindViewHolder (ViewHolder holder, int position) { //根据position来获取ViewHolder的类型 int itemViewType = this.getItemViewType(position); if (itemViewType == 0) { //获取 显示普通数据 Holder CustomViewHolder viewHolder = (CustomViewHolder) holder; String s = mStringList.get(position); //设置数据 viewHolder.setDatas(position, s); } else { //最后一个条目 获取刷新布局对应的Holder UpLoadViewHolder viewHolder = (UpLoadViewHolder) holder; viewHolder.setDatas(position); } } @Override public int getItemCount () { /** * 只有当显示的条目个数大于10 才启用上拉到底部加载更多数据功能 * 也就是只有当显示的条目个数大于10 时,才多返回一个条目 * 用来设置显示加载更多的布局 */ if (mStringList == null) { return 0; } else if (mStringList.size() > 10) { return mStringList.size() + 1; } else { return mStringList.size(); } } @Override public int getItemViewType (int position) { if (mStringList.size() > 10) { /** * 只有当显示的条目个数大于10 时,在显示最后一条数据时 * 此时是无数据内容,用来显示上拉刷新布局,这里返回1为标识 */ if (position == mStringList.size()) { //如果是最后一个条目 那么返回1 //用来加载显示刷新布局 return 1; } else { //用来加载显示普通布局 return 0; } } else { //用来加载显示普通布局 return 0; } }};
//普通加载项的ViewHolderprivate static class CustomViewHolder extends ViewHolder { private final TextView mTextView; public CustomViewHolder (View itemView) { super(itemView); mTextView = (TextView) itemView.findViewById(R.id.tv_item_text); } public void setDatas (int position, String s) { mTextView.setText(s); }}
//上拉加载更多的 ViewHolderprivate static class UpLoadViewHolder extends ViewHolder { private final TextView mTextView; public UpLoadViewHolder (View itemView) { super(itemView); mTextView = (TextView) itemView.findViewById(R.id.tv_loading_more); } public void setDatas (int position) { }}
3 RecyclerView 的 OnScrollListener (滑动监听事件) 中实现上拉加载数据功能
//设置滑动监听事件mRecyclerView.setOnScrollListener(mOnScrollListener);
//当前屏幕上显示的最后一个条目数据对应的位置private int mLastVisibleItemPosition;//当前屏幕显示的第一个条目数据对应的位置private int mFirstVisibleItemPosition;//获取当前RecyclerView完全显示出的第一个条目的位置private int mFirstCompletelyVisibleItemPosition;//获取当前RecyclerView完全显示出的最后一个条目的位置private int mLastCompletelyVisibleItemPosition;/** * RecyclerView是否滑动到了顶部 只有滑动到了顶部才可以启用下拉刷新功能 * 这里通过RecyclerView的布局管理者 mLinearLayoutManager来动态的获取当前屏幕上显示的RecyclerView的第一个条目对应的 角标索引 */private boolean mIsToTop = true;/** * 上拉加载更多数据 是否正在加载 * 当正在加载更多数据时,此时可能还会滑动RecyclerView * 为防止同时发起多次请求数据 所设置的标识 */private boolean mIsLoading = false;
/** * RecyclerView 的滑动监听事件 * 在这里可以判断RecyclerView是否滑动到了顶部 * 在这里用来判断RecyclerView是否滑动到了底部 */private OnScrollListener mOnScrollListener = new OnScrollListener() { @Override public void onScrolled (RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); //根据当前的布局管理都来获取显示的条目位置 if (mLinearLayoutManager != null) { //获取当前RecyclerView显示最后一个条目的位置 mLastVisibleItemPosition = mLinearLayoutManager.findLastVisibleItemPosition(); //获取当前RecyclerView显示的第一个条目的位置 mFirstVisibleItemPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); //获取当前RecyclerView完全显示出的最后一个条目的位置 mLastCompletelyVisibleItemPosition = mLinearLayoutManager.findLastCompletelyVisibleItemPosition(); //获取当前RecyclerView完全显示出的第一个条目的位置 mFirstCompletelyVisibleItemPosition = mLinearLayoutManager.findFirstCompletelyVisibleItemPosition(); /** * 当RecyclerView 显示的第一个条目 完全加载出来时 * mFirstVisibleItemPosition 为 0 * mFirstCompletelyVisibleItemPosition 也为0 * 当RecyclerView 显示的第一个条目 并没有完全加载出来,也就是显示了一半(显示不完全 ) * mFirstVisibleItemPosition 为 0 * mFirstCompletelyVisibleItemPosition 为1 * * 所以 当mFirstCompletelyVisibleItemPosition 为 0 表示 完全滑动到了顶部 */ if (mFirstCompletelyVisibleItemPosition == 0) { //更新滑动到顶部标识 mIsToTop = true; Log.e("scroll ", "滑动到顶部 "); } else { //更新滑动到顶部标识 false不在顶部 mIsToTop = false; //获取当前屏幕上显示的条目的个数 int childCount = mLinearLayoutManager.getChildCount(); //获取总共的条目个数 int itemCount = mLinearLayoutManager.getItemCount(); //当显示的条目数据大于10条时 才启用上拉加载更多功能 if (itemCount > 10) { //当显示出最后一个条目时 if (mLastVisibleItemPosition==itemCount-1) { log("大于10 可以加载更多 " + itemCount); //加载更多 if (!mIsLoading) { //更新加载标识 mIsLoading = true; //加载更多数据 loadMoreData(); } } } else { log("小于10 不可以加载更多 " + itemCount + " " + childCount); } } } } @Override public void onScrollStateChanged (RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (mViewHolderAdapter != null) { //当滑动停止时 if (newState == RecyclerView.SCROLL_STATE_IDLE) { } } }};
走到这里呢就基本上可以实现 上拉加载更多数据的功能了
4 RecyclerView 的 OnTouchListener (触摸监听事件) 中实现下拉刷新数据功能
//设置触摸监听事件mRecyclerView.setOnTouchListener(mOnTouchListener);
private OnTouchListener mOnTouchListener = new OnTouchListener() { @Override public boolean onTouch (final View v, MotionEvent event) { switch (event.getAction()) { //手指按下 case MotionEvent.ACTION_DOWN: .... .... ....(4.1 中代码说明) break; //手指移动 case MotionEvent.ACTION_MOVE: .... .... .... break; //手指抬起 case MotionEvent.ACTION_UP: .... .... .... break; }};
/** * 下拉刷新状态标识 */public enum RefresState { PULL_DEFAULE,//开始默认 PULL_SHOW,//显示释放加载 PULL_LOADING,//显示正在加载中 PULL_LOADING_FINISH//显示刷新完毕}
4.1 手指按下时
//手指按下的位置private float mDownY;//手指按下时 刷新控件的位置 private int mPullTop;//手指按下时 RecyclerView控件的位置private int mRecyTop;//手指按下标识public boolean mIsDown = false;
case MotionEvent.ACTION_DOWN: /** * mValueAnimator 是当手指离开屏幕时,页面显示布局文件滚回原始默认位置或者指定位置的 动画 * * 当手指按下去时,如果当前的下拉刷新布局或者 RecyclerView 正在移动,需要停止 */ if (mValueAnimator != null) { if (mValueAnimator.isRunning() || mValueAnimator.isStarted()) { mValueAnimator.cancel(); } } //获取手指按下的纵坐标 mDownY = event.getRawY(); //获取刷新控件当前的位置 mPullTop = mPullRefshLayout.getTop(); //获取列表控件当前的位置 mRecyTop = mRecyclerView.getTop(); //手指按下的标识 mIsDown = true; log("top is mRecyTop" + mRecyTop + " mPullTop " + mPullTop); break;
4.2 手指移动时
case MotionEvent.ACTION_MOVE: //获取实时手指触摸屏幕的 Y轴位置 float moveY = event.getRawY(); //计算 手指移动的距离 int flagY = (int) (moveY - mDownY); /** * 缩小 要不布局会随着滑动的距离变化太大 * flagY >0 向下滑动 * flagY < 0向上滑动 */ flagY = flagY / 2; //当RecyclerView滑动到顶部的时候才可以拖动 if (mIsToTop) { if (mCurrentRefresState == RefresState.PULL_DEFAULE) { /** * PULL_DEFAULE 状态时 RecyclerView处于屏幕的顶部 * 向上滑动时不做处理 * 向下滑动时 处理移动 */ if (flagY >= 0) { /** * 当下滑到一定距离(显示刷新布局 mPullRefshLayout完全显示出来后) * 更新状态为 PULL_SHOW * 更新刷新布局的显示 */ if (mPullRefshLayout.getTop() >= 0) { if (mCurrentRefresState != RefresState.PULL_SHOW) { mCurrentRefresState = RefresState.PULL_SHOW; mPullRefTextView.setText("释放刷新"); } } //RecyclerView 位置限定 int recyTop = mRecyTop + flagY; if (recyTop <= 0) { recyTop = 0; } int recyBottom = mRecyclerView.getHeight() + recyTop; //下拉刷新位置限定 int pullTop = mPullTop + flagY; if (pullTop <= -mPullRefshLayoutHeight) { pullTop = -mPullRefshLayoutHeight; } int pullBottom = mPullRefshLayout.getHeight() + pullTop; //重新设置RecyclerView的显示 setRecyclerViewLayout(getRecyclerViewRect(recyTop, recyBottom)); //重新设置刷新布局文件的显示 setPullRefreshLayout(getPullRefreshLayoutRect(pullTop, pullBottom)); return true; } } else if (mCurrentRefresState == RefresState.PULL_SHOW) { int recyTop = mRecyTop + flagY; int recyBottom = mRecyclerView.getHeight() + recyTop; //更新列表的 int pullTop = mPullTop + flagY; if (pullTop <= -mPullRefshLayoutHeight) { pullTop = -mPullRefshLayoutHeight; } int pullBottom = mPullRefshLayout.getHeight() + pullTop; /** * mPullRefshLayout没完全显示出来 * 也就是 mPullRefshLayout.getTop() < 0 * 更新为 PULL_DEFAULE 状态 */ if (mPullRefshLayout.getTop() < 0) { if (mCurrentRefresState != RefresState.PULL_DEFAULE) { mCurrentRefresState = RefresState.PULL_DEFAULE; mPullRefTextView.setText("下拉刷新"); } } //重新设置RecyclerView的显示 setRecyclerViewLayout(getRecyclerViewRect(recyTop, recyBottom)); //重新设置刷新布局文件的显示 setPullRefreshLayout(getPullRefreshLayoutRect(pullTop, pullBottom)); return true; } else if (mCurrentRefresState == RefresState.PULL_LOADING) { /** * 正在加载中 状态 * * 在这里设置的是 如果下拉刷新正在进行中 * 那么只允许下拉 不可上滑 */ if (flagY > 0) { int recyTop = mRecyTop + flagY; int recyBottom = mRecyclerView.getHeight() + recyTop; //更新列表的 int pullTop = mPullTop + flagY; int pullBottom = mPullRefshLayout.getHeight() + pullTop; //重新设置RecyclerView的显示 setRecyclerViewLayout(getRecyclerViewRect(recyTop, recyBottom)); //重新设置刷新布局文件的显示 setPullRefreshLayout(getPullRefreshLayoutRect(pullTop, pullBottom)); return true; } else { return true; } } else if (mCurrentRefresState == RefresState.PULL_LOADING_FINISH) { /** * 加载完成 状态 * * 在这里设置的是 如果下拉刷新正在进行中 * 那么只允许下拉 不可上滑 */ int recyTop = mRecyTop + flagY; if (recyTop <= 0) { recyTop = 0; } int recyBottom = mRecyclerView.getHeight() + recyTop; //更新列表的 int pullTop = mPullTop + flagY; if (pullTop <= -mPullRefshLayoutHeight) { pullTop = -mPullRefshLayoutHeight; } int pullBottom = mPullRefshLayout.getHeight() + pullTop; //重新设置RecyclerView的显示 setRecyclerViewLayout(getRecyclerViewRect(recyTop, recyBottom)); //重新设置刷新布局文件的显示 setPullRefreshLayout(getPullRefreshLayoutRect(pullTop, pullBottom)); return true; } }
4.3 手指抬起时
case MotionEvent.ACTION_UP: //手指抬起 mIsDown = false; //获取RecyclerView当前的位置 final int recyUpTop = mRecyclerView.getTop(); /** * PULL_DEFAULE 状态,弹回初始默认隐藏页面 */ if (mCurrentRefresState == RefresState.PULL_DEFAULE) { //不刷新,隐藏 mValueAnimator = ValueAnimator.ofFloat(1f, 0f); mValueAnimator.setDuration(mPullDuration); mValueAnimator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate (ValueAnimator animation) { //0 -- 1 Float value = (Float) animation.getAnimatedValue(); int recyTop = (int) (recyUpTop * value); int recyBottom = mRecyclerView.getHeight() + recyTop; int pullTop = recyTop - mPullRefshLayoutHeight; int pullBottom = mPullRefshLayout.getHeight() + pullTop; //重新设置RecyclerView的显示 setRecyclerViewLayout(getRecyclerViewRect(recyTop, recyBottom)); //重新设置刷新布局文件的显示 setPullRefreshLayout(getPullRefreshLayoutRect(pullTop, pullBottom)); } }); //开启 mValueAnimator.start(); } else if (mCurrentRefresState == RefresState.PULL_SHOW || mCurrentRefresState == RefresState.PULL_LOADING) { /** * PULL_SHOW 状态 * PULL_LOADING 状态 * 都将进入显示 加载中数据状态 */ log("up state is " + mCurrentRefresState); //设置文字 mPullRefTextView.setText("正在加载中"); //正在加载中状态 if (mCurrentRefresState != RefresState.PULL_LOADING) { mCurrentRefresState = RefresState.PULL_LOADING; //加载更多数据方法 loadingRefresDataFunction(); } //刷新 显示正在加载中 mValueAnimator = ValueAnimator.ofFloat(0f, 1f); mValueAnimator.setDuration(mPullDuration); mValueAnimator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate (ValueAnimator animation) { //0 -- 1 Float value = (Float) animation.getAnimatedValue(); int recyTop = (int) (recyUpTop - ((recyUpTop - mPullRefshLayoutHeight) * value)); int recyBottom = mRecyclerView.getHeight() + recyTop; int pullTop = recyTop - mPullRefshLayoutHeight; int pullBottom = mPullRefshLayout.getHeight() + pullTop; //重新设置RecyclerView的显示 setRecyclerViewLayout(getRecyclerViewRect(recyTop, recyBottom)); //重新设置刷新布局文件的显示 setPullRefreshLayout(getPullRefreshLayoutRect(pullTop, pullBottom)); } }); mValueAnimator.addListener(new AnimatorListener() { @Override public void onAnimationStart (Animator animation) { } @Override public void onAnimationEnd (Animator animation) { mCurrentRefresState = RefresState.PULL_LOADING; } @Override public void onAnimationCancel (Animator animation) { } @Override public void onAnimationRepeat (Animator animation) { } }); mValueAnimator.start(); } else if (mCurrentRefresState == RefresState.PULL_LOADING_FINISH) { log("up state is loading_finish "); //设置文字 mPullRefTextView.setText("已更新数据完成"); //关闭刷新 mValueAnimator = ValueAnimator.ofFloat(1f, 0f); mValueAnimator.setDuration(mPullDuration); mValueAnimator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate (ValueAnimator animation) { //0 -- 1 Float value = (Float) animation.getAnimatedValue(); int recyTop = (int) (recyUpTop * value); int recyBottom = mRecyclerView.getHeight() + recyTop; int pullTop = recyTop - mPullRefshLayoutHeight; int pullBottom = mPullRefshLayout.getHeight() + pullTop; //重新设置RecyclerView的显示 setRecyclerViewLayout(getRecyclerViewRect(recyTop, recyBottom)); //重新设置刷新布局文件的显示 setPullRefreshLayout(getPullRefreshLayoutRect(pullTop, pullBottom)); } }); mValueAnimator.addListener(new AnimatorListener() { @Override public void onAnimationStart (Animator animation) { } @Override public void onAnimationEnd (Animator animation) { //更新为初始状态 mCurrentRefresState = RefresState.PULL_DEFAULE; } @Override public void onAnimationCancel (Animator animation) { } @Override public void onAnimationRepeat (Animator animation) { } }); mValueAnimator.start(); } break;
4.4 重新设置RecyclerView与pullRefreshLayout布局大小的方法
/** * 将RecyclerView 的left top right bottom 封装到Rect */public Rect getRecyclerViewRect (int top, int bottom) { return new Rect(mRecyclerView.getLeft(), top, mRecyclerView.getWidth(), bottom);}/** * 重新布局RecyclerView 并进行刷新 */public void setRecyclerViewLayout (Rect rect) { mRecyclerView.layout(rect.left, rect.top, rect.right, rect.bottom); mRecyclerView.invalidate();}public Rect getPullRefreshLayoutRect (int top, int bottom) { return new Rect(mPullRefshLayout.getLeft(), top, mPullRefshLayout.getWidth(), bottom);}public void setPullRefreshLayout (Rect rect) { mPullRefshLayout.layout(rect.left, rect.top, rect.right, rect.bottom); mPullRefshLayout.invalidate();}
4.5 加载完数据后需要关闭加载中状态
public void closePullRefresh () { log("加载完成"); //加载完成 mCurrentRefresState = RefresState.PULL_LOADING_FINISH; //更新显示 mPullRefTextView.setText("刷新数据完成"); if (mIsDown) { //正在滑动中不需要结束布局显示 } else { log("结束刷新"); closePullRefresh(true); }}public void closePullRefresh (boolean flag) { if (flag) { mValueAnimator = ValueAnimator.ofFloat(1f, 0f); mValueAnimator.setDuration(mPullDuration); mValueAnimator.addListener(new AnimatorListener() { @Override public void onAnimationStart (Animator animation) { } @Override public void onAnimationEnd (Animator animation) { mCurrentRefresState = RefresState.PULL_DEFAULE; //更新列表 mViewHolderAdapter.notifyDataSetChanged(); } @Override public void onAnimationCancel (Animator animation) { } @Override public void onAnimationRepeat (Animator animation) { } }); mValueAnimator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate (ValueAnimator animation) { //1 --- 0 Float value = (Float) animation.getAnimatedValue(); int recyTop = (int) (mPullRefshLayoutHeight * value); int recyBottom = mRecyclerView.getHeight() + recyTop; int pullTop = recyTop - mPullRefshLayoutHeight; int pullBottom = mPullRefshLayout.getHeight() + pullTop; //重新设置RecyclerView的显示 setRecyclerViewLayout(getRecyclerViewRect(recyTop, recyBottom)); //重新设置刷新布局文件的显示 setPullRefreshLayout(getPullRefreshLayoutRect(pullTop, pullBottom)); } }); mValueAnimator.start(); } }
阅读全文
1 0
- Android RecyclerView(八)设置自定义 下拉刷新 与 上拉加载数据
- RecyclerView的下拉刷新数据 与上拉加载更多
- 自定义下拉刷新上拉加载控件(SwipeRefreshLayout + recyclerView)
- Android SwipeRefreshLayout+RecyclerView下拉刷新与上拉加载
- android-- 自定义下拉刷新上拉加载控件(SwipeRefreshLayout + recyclerView)
- android 自定义下拉刷新上拉加载控件(SwipeRefreshLayout + recyclerView)
- Android 自定义下拉刷新上拉加载
- YRecyclerView自定义下拉刷新上拉加载更多的RecyclerView
- 自定义RecyclerView实现下拉刷新和上拉加载
- 自定义RecyclerView添加下拉刷新和上拉加载功能
- 完全自定义RecyclerView下拉刷新上拉加载
- android 打造真正的下拉刷新上拉加载recyclerview(三):下拉刷新上拉加载
- android 打造真正的下拉刷新上拉加载recyclerview(三):下拉刷新上拉加载
- 自定义控件(四)-下拉刷新与上拉加载
- Android-详解RecyclerView+BGARefreshLayout实现自定义下拉刷新、上拉加载和侧滑删除效果
- RecyclerView的上拉刷新与下拉加载
- Swiperefreshlayout与Recyclerview下拉刷新和上拉加载
- RecyclerView上拉刷新与下拉加载封装
- 编程小技巧
- android
- dpdk学习之多进程simple_mp源代码分析
- VMware虚拟机Mac OS X如何调整扩展硬盘大小
- 面试题 49: 把字符串转换为整数
- Android RecyclerView(八)设置自定义 下拉刷新 与 上拉加载数据
- 通过编排管理 Docker 容器
- asp 时间截取
- dede栏目添加自定义字段方法
- 如何利用远程导入sql脚本到plsql中
- php框架学习---yii2高级版安装
- Spring IOC和AOP 原理彻底搞懂
- Android打包—Ant
- 7/5杂