(六)安卓框架搭建之RecyclerView和Adapter以及列表案例

来源:互联网 发布:淘宝零食店货源哪里来 编辑:程序博客网 时间:2024/05/17 23:25

recycalview和adapter
recycleview 的出现就是来替代listview,并且其性能上做了很多优化。今天用的这个是取自第三方的Xrecycleview,没错,这次又是站在了巨人的肩膀上。选Xrecycleview的原因是之前用这个写过一个自定义的头部刷新view.而且它在github上,评价也蛮好。

有点小遗憾就是刷新效果很老气。所以我决定重新写一个RefresHeader.如下

package com.example.burro.demo.appframework.recyclerview.xrecyclerview.custom;import android.animation.ValueAnimator;import android.content.Context;import android.graphics.drawable.AnimationDrawable;import android.os.Handler;import android.util.AttributeSet;import android.view.Gravity;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.LinearLayout;import com.example.burro.demo.appframework.R;import com.example.burro.demo.appframework.recyclerview.xrecyclerview.BaseRefreshHeader;import com.example.burro.demo.appframework.recyclerview.xrecyclerview.SimpleViewSwitcher;/**自定义刷新view *Created by ex.zhong on 2017/9/17. */public class CustomerRefreshHeader extends LinearLayout implements BaseRefreshHeader {    private LinearLayout mContainer;    private ImageView mArrowImageView;    private SimpleViewSwitcher mProgressBar;    private int mState = STATE_NORMAL;    public int mMeasuredHeight;    private AnimationDrawable mAnimationDrawable;    public CustomerRefreshHeader(Context context) {        super(context);        initView();    }    /**     * @param context     * @param attrs     */    public CustomerRefreshHeader(Context context, AttributeSet attrs) {        super(context, attrs);        initView();    }    private void initView() {        // 初始情况,设置下拉刷新view高度为0        mContainer = (LinearLayout) LayoutInflater.from(getContext()).inflate(                R.layout.custom_listview_header, null);        LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);        lp.setMargins(0, 0, 0, 0);        this.setLayoutParams(lp);        this.setPadding(0, 0, 0, 0);        addView(mContainer, new LayoutParams(LayoutParams.MATCH_PARENT, 0));        setGravity(Gravity.BOTTOM);        mArrowImageView = (ImageView)findViewById(R.id.listview_header_arrow);        //init the progress view        mProgressBar = (SimpleViewSwitcher)findViewById(R.id.listview_header_progressbar);        ImageView progressView= new ImageView(getContext());        progressView.setImageResource(R.drawable.refresh_headview);        mAnimationDrawable=(AnimationDrawable)progressView.getDrawable();        mProgressBar.setView(progressView);        measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);        mMeasuredHeight = getMeasuredHeight();    }    public void setProgressStyle(int style) {    }    //设置要动画图片    public void setProgressStyle(ImageView imageView) {        if(imageView != null&&imageView.getDrawable()!=null){            mProgressBar.setView(imageView);            mAnimationDrawable= (AnimationDrawable) imageView.getDrawable();        }    }    //设置背景图片    public void setRefreshBackground(int color) {        mContainer.setBackgroundColor(color);    }    public void setArrowImageView(int resid){        mArrowImageView.setImageResource(resid);    }    public void setState(int state) {        if (state == mState) return ;        if (state == STATE_REFRESHING) {    // 显示进度            mArrowImageView.clearAnimation();            mArrowImageView.setVisibility(View.INVISIBLE);            mProgressBar.setVisibility(View.VISIBLE);            mAnimationDrawable.start();            smoothScrollTo(mMeasuredHeight);        } else if(state == STATE_DONE) {            mArrowImageView.setVisibility(View.VISIBLE);            mProgressBar.setVisibility(View.INVISIBLE);            mAnimationDrawable.stop();        } else {    // 显示箭头图片            mArrowImageView.setVisibility(View.VISIBLE);            mProgressBar.setVisibility(View.INVISIBLE);            mAnimationDrawable.stop();        }        mState = state;    }    public int getState() {        return mState;    }    @Override    public void refreshComplete(){        setState(STATE_DONE);        new Handler().postDelayed(new Runnable(){            public void run() {                reset();            }        }, 200);    }    public void setVisibleHeight(int height) {        if (height < 0) height = 0;        LayoutParams lp = (LayoutParams) mContainer .getLayoutParams();        lp.height = height;        mContainer.setLayoutParams(lp);    }    public int getVisibleHeight() {        LayoutParams lp = (LayoutParams) mContainer.getLayoutParams();        return lp.height;    }    @Override    public void onMove(float delta) {        if(getVisibleHeight() > 0 || delta > 0) {            setVisibleHeight((int) delta + getVisibleHeight());            if (mState <= STATE_RELEASE_TO_REFRESH) { // 未处于刷新状态,更新箭头                if (getVisibleHeight() > mMeasuredHeight) {                    setState(STATE_RELEASE_TO_REFRESH);                }else {                    setState(STATE_NORMAL);                }            }        }    }    @Override    public boolean releaseAction() {        boolean isOnRefresh = false;        int height = getVisibleHeight();        if (height == 0) // not visible.            isOnRefresh = false;        if(getVisibleHeight() > mMeasuredHeight &&  mState < STATE_REFRESHING){            setState(STATE_REFRESHING);            isOnRefresh = true;        }        // refreshing and header isn't shown fully. do nothing.        if (mState == STATE_REFRESHING && height <=  mMeasuredHeight) {            //return;        }        if (mState != STATE_REFRESHING) {            smoothScrollTo(0);        }        if (mState == STATE_REFRESHING) {            int destHeight = mMeasuredHeight;            smoothScrollTo(destHeight);        }        return isOnRefresh;    }    public void reset() {        smoothScrollTo(0);        new Handler().postDelayed(new Runnable() {            public void run() {                setState(STATE_NORMAL);            }        }, 500);    }    private void smoothScrollTo(int destHeight) {        ValueAnimator animator = ValueAnimator.ofInt(getVisibleHeight(), destHeight);        animator.setDuration(300).start();        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation)            {                setVisibleHeight((int) animation.getAnimatedValue());            }        });        animator.start();    }}

修改的思路起始很简单。只是把以前刷新时的旋转动画换成了帧动画。当下拉或刷新结束时。设置静态图片。当然要对核心的XRecyclerViewy也要稍加修改,使其适配我的CustomerRefreshHeader.布局请到demo中查看

adapter

XRecyclerViewy封装的很好,但是没有对他的兄弟adapter进行封装优化。BaseRecyclerViewAdapter是adapter的基类,直接贴上封装内容:
BaseRecyclerViewAdapter

package com.example.burro.demo.appframework.adapter;import android.content.Context;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import java.util.ArrayList;import java.util.List;/**Adapter基类 * Created by ex.zhong on 2017/9/29. */public abstract class BaseRecyclerViewAdapter<T> extends RecyclerView.Adapter<BaseViewHolder>{    protected Context mContext;    private LayoutInflater inflater;    private List<T> datas;    private int layoutId;    protected OnItemClickListner onItemClickListner;//单击事件    protected OnItemLongClickListner onItemLongClickListner;//长按单击事件    public BaseRecyclerViewAdapter(Context context, OnItemClickListner onItemClickListner) {        this.mContext = context;        this.datas = new ArrayList<>();        this.layoutId = initLayoutInflater();        this.inflater = LayoutInflater.from(context);        this.onItemClickListner=onItemClickListner;    }    protected abstract int initLayoutInflater();    @Override    public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        BaseViewHolder holder = new BaseViewHolder(inflater.inflate(layoutId, parent, false));        //可全局在此设置增加外层效果布局//        MaterialRippleLayout.on(holder.getView(R.id.ll_all))//                .rippleOverlay(true)//                .rippleAlpha(0.2f)//                .rippleColor(context.getResources().getColor(R.color.colorAccent))//                .rippleHover(true)//                .create();        return holder;    }    @Override    public void onBindViewHolder(final BaseViewHolder holder, final int position) {        holder.getRootView().setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                if(onItemClickListner!=null) onItemClickListner.onItemClickListner(v,position);            }        });        bindData(holder, datas.get(position), position);    }    protected abstract void bindData(BaseViewHolder holder, T data, int position);    @Override    public int getItemCount() {        return datas == null ? 0 : datas.size();    }    //单击事件接口    public interface OnItemClickListner {        void onItemClickListner(View v, int position);    }    //长按事件接口    public interface OnItemLongClickListner {        void onItemLongClickListner(View v, int position);    }    //更新数据    public void updateData(List<T> list) {        datas.clear();        if(list!=null){            datas.addAll(list);        }        notifyDataSetChanged();    }    //增加更多    public void addMoreData(List<T> list){        if(list!=null){            datas.addAll(list);        }        notifyDataSetChanged();    }    //获取数据集合数据    public List<T> getDataList(){        return datas;    }}

BaseViewHolder

package com.example.burro.demo.appframework.adapter;import android.support.v7.widget.RecyclerView;import android.util.SparseArray;import android.view.View;/**全能的ViewHolder * Created by ex.zhong on 2017/9/29. */public class BaseViewHolder extends RecyclerView.ViewHolder{    private SparseArray<View> views;    public BaseViewHolder(View view) {        super(view);        this.views = new SparseArray<>();    }    public <T extends View> T getView(int viewId) {        View view = views.get(viewId);        if (view == null) {            view = itemView.findViewById(viewId);            views.put(viewId, view);        }        return (T) view;    }    public View getRootView() {        return itemView;    }}

我是不推荐直接的引用第三方的包,试想如果需求要调整,那岂不是每个页面都要去改动?所以!当然!要封装一个公用的类来继承它。我这里写一个类ComRecyclerView继承自XRecyclerView,各位也可以根据具体使用情况自由发挥!

package com.example.burro.demo.appframework.recyclerview;import android.content.Context;import android.support.v7.widget.LinearLayoutManager;import android.util.AttributeSet;import com.example.burro.demo.appframework.R;import com.example.burro.demo.appframework.recyclerview.xrecyclerview.ProgressStyle;import com.example.burro.demo.appframework.recyclerview.xrecyclerview.XRecyclerView;/**通用ComRecyclerView * Created by ex.zhong on 2017/9/27. */public class ComRecyclerView extends XRecyclerView {    public ComRecyclerView(Context context) {        super(context);        initView(context);    }    public ComRecyclerView(Context context, AttributeSet attrs) {        super(context, attrs);        initView(context);    }    public ComRecyclerView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        initView(context);    }    private void initView(Context context) {        //  headerView的添加,可更具需要,在页面上动态设置//        View header = LayoutInflater.from(context).inflate(R.layout.recyclerview_header, (ViewGroup)findViewById(android.R.id.content),false);//        mRecyclerView.addHeaderView(header);        //添加刷新动画        //默认线性布局,如需gridView,可重新设置        LinearLayoutManager layoutManager = new LinearLayoutManager(context);        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);        this.setLayoutManager(layoutManager);        this.setRefreshProgressStyle(ProgressStyle.BallSpinFadeLoader);        this.setLoadingMoreProgressStyle(ProgressStyle.BallRotate);        this.setArrowImageView(R.mipmap.mloading_0);    }}

先前写过的电影列表中用到的Adapter,看看是不是很简洁!

电影列表适配adapter

为了保证demo的完整性,结合之前所写以及上述RecyclerView和Adapter的封装,接下来完善一下列表页面。我把test部分的内容全部移进movie里面。并增加了详情页面,页面跳转、MainActivity里增加新建的MovieListFragment等。由于这部分主要是业务内容。不多作说明,可以到源码中查看


下一篇将进一步完善框架

相关链接

(七)安卓框架搭建之其他必备要素的封装或引入

github源码地址

阅读全文
0 0
原创粉丝点击