自定义的RecyclerView, 下拉刷新,加载更多.

来源:互联网 发布:宋太祖宋真宗去世知乎 编辑:程序博客网 时间:2024/05/22 15:01

编写用到的下拉刷新的布局文件

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              android:layout_width="match_parent"              android:layout_height="wrap_content"              android:background="#f00"              android:gravity="center"              android:orientation="vertical"    >    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/ll"        >        <TextView            android:id="@+id/status"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:gravity="center"            android:text="显示一些东西"            android:textColor="#000"            />    </LinearLayout></LinearLayout>

自定义RecyclerView 封装了下拉刷新和加载更多的功能

/** * 下拉刷新和加载更多的 自定View * Created by SwmIsMe on 2017/3/2. */public class MyRecyclerView extends RecyclerView {    public final static int STATE_NORMAL = 0;    public final static int STATE_READY = 1;    public final static int STATE_REFRESHING = 2;    MyLoadRefreshAdapter mLoadRefreshAdapter;    View headerView, footerView;    private int mState = STATE_NORMAL;    //    头布局的高度    int headerViewHeight;    //    是否正在触摸    boolean isOnTouching;    TextView status;    boolean isRefresh;    private LinearLayout mLl;    private LinearLayout.LayoutParams mParams;    private LayoutManager mLayoutManager;    public MyRecyclerViewListener getMyRecyclerViewListener() {        return myRecyclerViewListener;    }    //    设置 监听    public void setMyRecyclerViewListener(MyRecyclerViewListener myRecyclerViewListener) {        this.myRecyclerViewListener = myRecyclerViewListener;    }    MyRecyclerViewListener myRecyclerViewListener;    public MyRecyclerView(Context context) {        super(context);    }    public MyRecyclerView(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);    }    public MyRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);    }    int lastX, lastY;    @Override    public boolean onTouchEvent(MotionEvent e) {        int x = (int) e.getX();        int y = (int) e.getY();        switch (e.getAction()) {            case MotionEvent.ACTION_DOWN:                break;            case MotionEvent.ACTION_MOVE:                isOnTouching = true;//                获取到 轮播的view                View view1 = this.getChildAt(1);//                获取到  轮播的view安排的位置.                int loopViewPagerPosition = this.getChildLayoutPosition(view1);//                如果 轮播的view安排(layout)的位置. 是第一个 触发下拉刷新的操作.                if (loopViewPagerPosition == 1) {                    if (lastY == 0) {                        lastY = y;                    }                    int dy = lastY - y;                    int dx = lastX - x;                    int yabs = Math.abs(dy);                    int xabs = Math.abs(dx);                    if (yabs > xabs) {                        isRefresh = true;                        changeHeight(dy);                        this.requestDisallowInterceptTouchEvent(true);                    } else {                        this.requestDisallowInterceptTouchEvent(false);                    }                    lastX = x;                    lastY = y;                }                break;            case MotionEvent.ACTION_UP:            case MotionEvent.ACTION_CANCEL:                isRefresh = false;                isOnTouching = false;//                归零                lastY = 0;//                开始刷新                if (mState == STATE_READY || mState == STATE_REFRESHING) {                    onStatusChange(STATE_REFRESHING);                    autoSize(0);                }//                回归到 隐藏的位置                if (mState == STATE_NORMAL) {                    autoSize(-headerViewHeight);                }                break;        }        return super.onTouchEvent(e);    }    //    通过改变 topMargin的值.改变高度    private void changeHeight(int dy) {        mParams.topMargin -= dy;        int margin = mParams.topMargin;        mLl.setLayoutParams(mParams);        setStateByHeight(margin, false);    }    /**     * 更新 头布局的高度     *     * @param targetHeight 要改变到的高度  当这个高度为0时,topMargin为0,显示整个刷新的界面,     *                     -headerViewHeight  隐藏头布局     */    public void autoSize(int targetHeight) {        int currentHeight = mParams.topMargin;//        从当前高度 到 目前高度,的动画变化值.        ValueAnimator objectAnimator = ValueAnimator.ofInt(currentHeight, targetHeight);//        设置下拉刷新的高度        objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                int animatedValue = (int) animation.getAnimatedValue();//                根据高度设置文本                setStateByHeight(animatedValue, true);                mParams.topMargin = animatedValue;                mLl.setLayoutParams(mParams);            }        });        objectAnimator.start();    }    //    设置加载更多的判断    @Override    public void setLayoutManager(final LayoutManager layout) {        super.setLayoutManager(layout);        this.addOnScrollListener(new OnScrollListener() {            @Override            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {                super.onScrolled(recyclerView, dx, dy);            }            @Override            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {                super.onScrollStateChanged(recyclerView, newState);                if (isRefresh) {                    return;                }                if (mState != STATE_NORMAL) {                    return;                }                LogUtils.e("new state" + newState);                //判断是否最后一item个显示出来                mLayoutManager = getLayoutManager();                //可见的item个数                int visibleChildCount = mLayoutManager.getChildCount();//                如果大于0 并且 状态不等于空闲 并且 没有在加载更多                if (visibleChildCount > 0 && newState == RecyclerView.SCROLL_STATE_IDLE && !isLoadMore) {//                    获取最后一个 view 除加载更多view                    View lastVisibleView = recyclerView.getChildAt(recyclerView.getChildCount() - 1);//                    返回给定子视图的适配器位置                    int lastVisiblePosition = recyclerView.getChildLayoutPosition(lastVisibleView);//                    如果 最后一个可见的位置 大于等于                    if (lastVisiblePosition >= mLayoutManager.getItemCount() - 1) {//                        加载更多view 可见                        footerView.setVisibility(VISIBLE);                        isLoadMore = true;//                        加载更多                        if (myRecyclerViewListener != null) {                            myRecyclerViewListener.onLoadMore();                        }                    } else {                        footerView.setVisibility(GONE);                    }                }            }        });    }    //    根据高度来设置 现在的状态    private void setStateByHeight(int height, boolean isAuto) {        if (mState == STATE_REFRESHING) {            return;        }//        如果 当前的高度 小于 头布局的高度        if (height < headerViewHeight) {            onStatusChange(STATE_NORMAL);        } else if (height > headerViewHeight) {            onStatusChange(STATE_READY);        } else if (height == headerViewHeight && !isOnTouching && !isAuto) {            onStatusChange(STATE_REFRESHING);        }    }    boolean isLoadMore;    public void onStatusChange(int status) {        mState = status;        switch (status) {            case STATE_READY:                this.status.setText("松开刷新...");                break;            case STATE_NORMAL:                this.status.setText("下拉刷新...");                break;            case STATE_REFRESHING:                this.status.setText("正在刷新...");                if (myRecyclerViewListener != null) {                    myRecyclerViewListener.onRefresh();                }                break;        }    }    //    初始化头尾布局 和 头尾view的适配器    @Override    public void setAdapter(Adapter adapter) {        ArrayList<View> headers = new ArrayList<>();        ArrayList<View> footers = new ArrayList<>();//        加载下拉刷新的布局文件        View refreshView = LayoutInflater.from(getContext()).inflate(R.layout.item_recycler_refresh, null);        headerView = refreshView;        status = (TextView) refreshView.findViewById(R.id.status);        mLl = (LinearLayout) refreshView.findViewById(R.id.ll);        headerView.post(new Runnable() {            @Override            public void run() {//                头布局真正的高度                headerViewHeight = headerView.getHeight();//                设置layout参数  隐藏头布局                mParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);                mParams.topMargin = -headerViewHeight;                mParams.width = ScreenUtils.screenW;                mLl.setLayoutParams(mParams);            }        });//        将头布局添加到 集合中        headers.add(headerView);//        初始化 尾布局        LinearLayout footerLayout = new LinearLayout(getContext());        footerLayout.setGravity(Gravity.CENTER);        footerLayout.setLayoutParams(new ViewGroup.LayoutParams(                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));        footers.add(footerLayout);        footerLayout.setPadding(0, 15, 0, 15);        footerLayout.addView(new ProgressBar(getContext(), null, android.R.attr.progressBarStyleSmall));        TextView text = new TextView(getContext());        text.setText("正在加载...");        footerLayout.addView(text);        footerView = footerLayout;        footerView.setVisibility(GONE);//        初始化 适配器        mLoadRefreshAdapter = new MyLoadRefreshAdapter(adapter, headers, footers);        super.setAdapter(mLoadRefreshAdapter);    }    public interface MyRecyclerViewListener {        void onRefresh();        void onLoadMore();    }    //    完成加载更多    public void setLoadMoreComplete() {//        直接隐藏 尾布局        footerView.setVisibility(GONE);        isLoadMore = false;    }    //    完成下拉刷新    public void setRefreshComplete() {        onStatusChange(STATE_NORMAL);        autoSize(-headerViewHeight);    }}

自定义 MyLoadRefreshAdapter 适配器

/** * 实现显示头部和尾部item的adapter,把头部尾部的事情交给这个adapter来做,其他的交给子adapter * Created by SwmIsMe on 2017/3/2. */public class MyLoadRefreshAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {    public ArrayList<View> headerViews = new ArrayList<>();    public ArrayList<View> footViews = new ArrayList<>();    public RecyclerView.Adapter adapter;    public MyLoadRefreshAdapter(RecyclerView.Adapter adapter, ArrayList<View> headerViews, ArrayList footViews) {        this.adapter = adapter;        this.headerViews = headerViews;        this.footViews = footViews;    }    MyLoadRefreshListener mLoadRefreshListener;    public MyLoadRefreshListener getLoadRefreshListener() {        return mLoadRefreshListener;    }    public void setLoadRefreshListener(MyLoadRefreshListener loadRefreshListener) {        mLoadRefreshListener = loadRefreshListener;    }    public interface MyLoadRefreshListener {        //        获取现在item的类型        void getNowItemType(int itemPosition);    }    @Override    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        if (viewType == RecyclerView.INVALID_TYPE) {            //头部item            return new RecyclerView.ViewHolder(headerViews.get(0)) {            };        } else if (viewType == (RecyclerView.INVALID_TYPE - 1)) {            //尾部item            return new RecyclerView.ViewHolder(footViews.get(0)) {            };        }        return adapter.onCreateViewHolder(parent, viewType);    }    @Override    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {        if (position >= 0 && position < headerViews.size()) {            return;        }//        交给 其他的适配器处理        if (adapter != null) {            int p = position - headerViews.size();            if (p < adapter.getItemCount()) {                adapter.onBindViewHolder(holder, p);            }        }    }    @Override    public int getItemViewType(int position) {        if (position >= 0 && position < headerViews.size()) {            //如果是头部则返回一个不可用的标识,表示这是头部item            return RecyclerView.INVALID_TYPE;        }        if (adapter != null) {            int p = position - headerViews.size();            if (p < adapter.getItemCount()) {                return adapter.getItemViewType(p);            }        }        return RecyclerView.INVALID_TYPE - 1;//默认返回表示是尾部的item    }    @Override    public int getItemCount() {        return getCount();    }    public int getCount() {        int count = headerViews.size() + footViews.size();        if (adapter != null) {            count += adapter.getItemCount();        }        return count;    }}

使用,添加监听

 mHomeRecyclerview.setLayoutManager(new LinearLayoutManager(getContext()));        MyHomeRecyclerviewAdapter adapter = new MyHomeRecyclerviewAdapter(LayoutInflater.from(getContext()));        mHomeRecyclerview.setAdapter(adapter);//        设置 下拉刷新 和加载更多的 监听        mHomeRecyclerview.setMyRecyclerViewListener(new MyRecyclerView.MyRecyclerViewListener() {            @Override            public void onRefresh() {                mHandler.postDelayed(new Runnable() {                    @Override                    public void run() {                        ToastUtils.showToast("onRefresh");                        mHomeRecyclerview.setRefreshComplete();                    }                }, 2000);            }            @Override            public void onLoadMore() {                mHandler.postDelayed(new Runnable() {                    @Override                    public void run() {                        ToastUtils.showToast("onLoadMore");                        mHomeRecyclerview.setLoadMoreComplete();                    }                }, 2000);            }        });
0 0
原创粉丝点击