一步一步的来封装自己的RecycleView

来源:互联网 发布:python中split函数 编辑:程序博客网 时间:2024/05/18 03:32

一步一步的来封装自己的RecycleView

项目中使用他人开源的RecycleView始终感觉不是很灵活,所以,自己动手,丰衣足食喽

还是菜鸟,所以,参考了好几个大牛的博客,摸索的一点一点的做,也希望有所提高。先是下拉刷新,主要想让刷新的view独立出来,并且可以自定义。看代码,看注释。

看图

使用SRecycleView:

//定义一个自己要使用的adapterDataAdapter dataAdapter = new  DataAdapter(this);dataAdapter.setData(list);sRecycleView.setLayoutManager(new LinearLayoutManager(this));//使用封装好的adapter包裹一下要使用的adapterSRecycleViewAdapter adapter = new SRecycleViewAdapter(this,dataAdapter);//自定义刷新ViewRefreshView refreshView = new RefreshView(this);adapter.setHeaderView(refreshView);sRecycleView.setAdapter(adapter);

自定义刷新view 只需要继承上类封装好的RefreshViewAbs,根据方法就可以动态实现view的效果 :

/** * Created by shen on 2016/8/19. */public class RefreshView extends RefreshViewAbs {    private TextView tv;    private View view;    public RefreshView(Context context) {        super(context);        init();    }    public void init(){        tv = (TextView) refreshView.findViewById(R.id.tv);    }    @Override    protected int getEmptyHeight() {        return ((int) (DensityUtils.dp2px(context,50)));    }    //自定义刷新使用的布局    @Override    protected int getLayoutView() {        return R.layout.refresh_view;    }    @Override    public void refresh() {        tv.setText("正在刷新....");    }    @Override    public void refreshComplete() {        tv.setText("刷新完成!");    }    @Override    public void releaseToRefresh() {        tv.setText("松开刷新");    }    @Override    public void noState() {        tv.setText("下拉刷新");    }}

封装好的刷新view的抽象类:

/** * Created by shen on 2016/8/19. */public abstract class RefreshViewAbs extends LinearLayout {    private int EMPTY_HEIGHT = 0;//刷新顶部空白高度    protected LinearLayout refreshView;    protected Context context;    private int measureHeight;    private RefreshViewState currentState = RefreshViewState.NO_STATE;    public abstract void refresh();    public abstract void refreshComplete();    public abstract void releaseToRefresh();    public abstract void noState();    private OnRefreshViewPullDownListening onRefreshViewPullDownListening;    public interface OnRefreshViewPullDownListening{        void scrolled(float dy);    }    public void setOnRefreshViewPullDownListening( OnRefreshViewPullDownListening onRefreshViewPullDownListening){        this.onRefreshViewPullDownListening = onRefreshViewPullDownListening;    }    public void mationActionUp(float rawY) {        if (getCurrentState() == RefreshViewAbs.RefreshViewState.RELEASE_TO_REFRESH) {            setState(RefreshViewAbs.RefreshViewState.IS_REFRESHING);            smoothScrollTo(getMeasureHeight());            refresh();        }        if (getCurrentState() == RefreshViewAbs.RefreshViewState.NO_STATE) {            smoothScrollTo(0);        }        if (getCurrentState() == RefreshViewAbs.RefreshViewState.IS_REFRESHING && getVisibleHeight() >= measureHeight) {            smoothScrollTo(getMeasureHeight());        }    }    public void setRefreshComplete() {        setState(RefreshViewAbs.RefreshViewState.NO_STATE);        refreshComplete();        new Handler().postDelayed(new Runnable() {            @Override            public void run() {                smoothScrollTo(0);            }        },300);    }    public enum RefreshViewState{        RELEASE_TO_REFRESH,NO_STATE,IS_REFRESHING    }    public RefreshViewState getCurrentState(){        return currentState;    }    public void setState(RefreshViewState state) {        this.currentState = state;    }    public RefreshViewAbs(Context context) {        super(context);        this.context = context;        init();    }    private void init() {        refreshView = (LinearLayout) LayoutInflater.from(context).inflate(getLayoutView(), null);        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);        params.setMargins(0,0,0,0);        this.setLayoutParams(params);        this.setPadding(0,0,0,0);        //初始化设置高度为零        this.addView(refreshView,new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,0));        measure(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);        measureHeight = getMeasuredHeight();        EMPTY_HEIGHT = getEmptyHeight();    }    protected abstract int getEmptyHeight();    //刷新view 的实际高度    public int getMeasureHeight(){             return measureHeight;    }    protected abstract int getLayoutView();    /**     * 当手指下滑时被调用     * */    public void putDown(float dy){        float countPullDown = getVisibleHeight() + dy/2;        L.d("refresh_view","countPullDown:"+countPullDown+"dy:"+dy+"measureHeight:"+measureHeight+"EMPTY_HEIGHT:"+EMPTY_HEIGHT);        if(countPullDown <0){            setRefreshViewHeight(0);            return;        }        if(countPullDown > measureHeight + EMPTY_HEIGHT){            countPullDown = measureHeight + EMPTY_HEIGHT;            return;        }        setRefreshViewHeight((int) (countPullDown));        if(onRefreshViewPullDownListening != null){            onRefreshViewPullDownListening.scrolled(dy);        }        if(currentState == RefreshViewState.IS_REFRESHING){            return;        }       if(countPullDown >= measureHeight){            setState(RefreshViewState.RELEASE_TO_REFRESH);            releaseToRefresh();        } else if(countPullDown >=0){            setState(RefreshViewState.NO_STATE);            noState();        }    }    /**     * 设置Refreshview 的可见高度     * */    private void setRefreshViewHeight(int dy) {        ViewGroup.LayoutParams layoutParams = refreshView.getLayoutParams();        layoutParams.height = dy;        refreshView.setLayoutParams(layoutParams);    }    //移动    public void smoothScrollTo(int destHeight) {        if(destHeight < 0){            return;        }        ValueAnimator animator = ValueAnimator.ofInt(getVisibleHeight(), destHeight);        animator.setDuration(200).start();        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                setRefreshViewHeight((int) animation.getAnimatedValue());            }        });        animator.start();    }    public int getVisibleHeight() {        return refreshView.getLayoutParams().height;    }    public int getTotalHeight(){        return measureHeight + EMPTY_HEIGHT;    }}

然后是封装过的Adapter,主要是利用type值的不同使position=0时是刷新的view:

/** * Created by shen on 2016/8/16. */public class SRecycleViewAdapter extends RecyclerView.Adapter {    private static final int TYPE_HEADER = 1;    private static final int TYPE_NORMAL = 2;    private Context context;    private RefreshViewAbs refreshView;    private RecyclerView.Adapter innerAdapter;    public SRecycleViewAdapter(Context context, RecyclerView.Adapter innerAdapter) {        this.context = context;        setAdapter(innerAdapter);    }    public void setHeaderView(RefreshViewAbs refreshView) {        this.refreshView = refreshView;    }    public RefreshViewAbs getRefreshView(){        return refreshView;    }    @Override    public int getItemViewType(int position) {        if(position == 0){            return TYPE_HEADER;        } else{            return TYPE_NORMAL;        }    }    @Override    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        if(viewType == TYPE_HEADER && refreshView != null){            return new HeaderHolder(refreshView);        }        return innerAdapter.onCreateViewHolder(parent,viewType);    }    @Override    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {        if(position == 0){            return;        }        int newPosition = holder.getLayoutPosition() -1;        innerAdapter.onBindViewHolder(holder,newPosition);    }    @Override    public int getItemCount() {        Log.d("recycleview","count:"+innerAdapter.getItemCount()+1);        return innerAdapter.getItemCount()+1;    }    public void setAdapter(RecyclerView.Adapter adapter) {        if (adapter != null) {            if (!(adapter instanceof RecyclerView.Adapter))                throw new RuntimeException("your adapter must be a RecyclerView.Adapter");        }        if (innerAdapter != null) {            notifyItemRangeRemoved(1, innerAdapter.getItemCount());            innerAdapter.unregisterAdapterDataObserver(mDataObserver);        }        this.innerAdapter = adapter;        innerAdapter.registerAdapterDataObserver(mDataObserver);        notifyItemRangeInserted(1, innerAdapter.getItemCount());    }    class HeaderHolder extends RecyclerView.ViewHolder {        public HeaderHolder(View itemView) {            super(itemView);        }    }    /**     * 监听传经来的adapter的变化,通知自己随之变化     * */    public RecyclerView.AdapterDataObserver mDataObserver = new RecyclerView.AdapterDataObserver() {        @Override        public void onChanged() {            super.onChanged();            notifyDataSetChanged();        }        @Override        public void onItemRangeChanged(int positionStart, int itemCount) {            notifyItemRangeChanged(positionStart +  1, itemCount);        }        @Override        public void onItemRangeInserted(int positionStart, int itemCount) {            notifyItemRangeInserted(positionStart +1, itemCount);        }        @Override        public void onItemRangeRemoved(int positionStart, int itemCount) {            notifyItemRangeRemoved(positionStart +  1, itemCount);        }        @Override        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {            notifyItemRangeChanged(fromPosition +  1, toPosition + 1+ itemCount);        }    };}

SRecycleView,重点处理ontouch方法:

/** * Created by shen on 2016/8/19. */public class SRecycleView extends RecyclerView {    private static final int IS_REFRESHING = 1000;    private static final int NORMAL = 1001;    private int currentRecycleViewState = NORMAL;    private RefreshViewAbs refreshView;    private SRecycleViewAdapter sRecycleViewAdapter;    private ISRecycleView.OnSRecycleViewListener onSRecycleViewListener;    private ISRecycleView.OnSRecycleViewScrollListening onSRecycleViewScrollListening;    public void setOnSRecycleViewListener(ISRecycleView.OnSRecycleViewListener onSRecycleViewListener) {        this.onSRecycleViewListener = onSRecycleViewListener;    }    public void setOnSRecycleViewScrollListening(ISRecycleView.OnSRecycleViewScrollListening onSRecycleViewScrollListening) {        this.onSRecycleViewScrollListening = onSRecycleViewScrollListening;    }    public SRecycleView(Context context) {        this(context, null);    }    public SRecycleView(Context context, @Nullable AttributeSet attrs) {        this(context, attrs, -1);    }    public SRecycleView(Context context, @Nullable AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        init();    }    private void init() {    }    @Override    public void setAdapter(Adapter adapter) {        super.setAdapter(adapter);        sRecycleViewAdapter = (SRecycleViewAdapter) getAdapter();        refreshView = sRecycleViewAdapter.getRefreshView();    }    float lastY = -1;    float lastX = -1;    @Override    public boolean onTouchEvent(MotionEvent e) {        switch (e.getAction()) {            case MotionEvent.ACTION_DOWN:                lastY = e.getRawY();                lastX = e.getRawX();                break;            case MotionEvent.ACTION_MOVE:                final float intervalY = e.getRawY() - lastY;                final float intervalX = e.getRawX() - lastX;                lastY = e.getRawY();                lastX = e.getRawX();                if (isOnTop()) {                    if (refreshView.getCurrentState() == RefreshViewAbs.RefreshViewState.IS_REFRESHING) {                        if(intervalY > 0){                            refreshView.putDown(intervalY);                        }                    } else {                        refreshView.putDown(intervalY);                        if (refreshView.getVisibleHeight() > 0) {//当refreshview出现时,静止recycleview本身的滑动,只是改变refreshview高度                            return false;                        }                    }                }                break;            case MotionEvent.ACTION_UP:                L.d("state", "state:" + refreshView.getCurrentState());                refreshView.mationActionUp(e.getRawY());                if (refreshView.getCurrentState() == RefreshViewAbs.RefreshViewState.IS_REFRESHING) {                    if (onSRecycleViewListener != null && SRecycleView.this.getRecycleViewState() != IS_REFRESHING) {                        setRecycleViewState(IS_REFRESHING);                        onSRecycleViewListener.refresh();                    }                }                break;        }        return super.onTouchEvent(e);    }    private void setRecycleViewState(int state) {        this.currentRecycleViewState = state;    }    public int getRecycleViewState() {        return currentRecycleViewState;    }    private boolean isOnTop() {        if (refreshView.getParent() != null) {            return true;        } else {            return false;        }    }    @Override    public void onScrolled(int dx, int dy) {        if(onSRecycleViewScrollListening != null){            onSRecycleViewScrollListening.onScrolled(dx,dy);        }    }    public void refreshComplete() {        setRecycleViewState(NORMAL);        refreshView.setRefreshComplete();    }}
0 0