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 = "\@2017ICP17005075-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
原创粉丝点击