Android编程思想,面向对象程序设计第五篇——继承(下)业务逻辑抽象化

来源:互联网 发布:java带参数的构造函数 编辑:程序博客网 时间:2024/04/24 15:31

上一节讲到继承举了Activity的列子,说明了使用继承在父类做一些共有的操作的好处。这一节我们将以RecyclerView的Adapter为列子,讲一下使用继承,把业务逻辑抽象出来,放在父类的好处。我们直接看例子:

T是泛型,使用泛型来表示我们列表的数据类型
public abstract class BaseRecyclerViewAdapter<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
    private View           mHeaderView;
    private View           mFooterView;
    protected ArrayList<T> mBeans = new ArrayList<T>();
    private int            mHeaderCount;
    private int            mFooterCount;
    protected Context      mContext;


    public BaseRecyclerViewAdapter(Context context, ArrayList<T> beans){
        mContext  = context;
        if(beans != null){
            mBeans    = beans;
        }
    }


//设置RecyclerView的头部
    public void setHeaderView(View headerView){
        mHeaderView = headerView;
    }


//设置RecyclerView的尾部
    public void setFooterView(View footerView){
        mFooterView = footerView;
    }


    private static final int VIEW_TYPE_HEADER            = 0;
    private static final int VIEW_TYPE_FOOTER            = 1;
    private static final int VIEW_TYPE_NORMAL            = 2;


//计算下一个item的视图类型
    @Override
    public int getItemViewType(int position) {
        mHeaderCount  = null == mHeaderView ? 0 : 1;
        mFooterCount  = null == mFooterView ? 0 : 1;
        if(position < mHeaderCount){
            return  VIEW_TYPE_HEADER;
        }else if(position >= (mHeaderCount + mBeans.size())){
            return VIEW_TYPE_FOOTER;
        }else{
            return VIEW_TYPE_NORMAL;
        }
    }


    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        RecyclerView.ViewHolder viewHolder = null;
        if(viewType == VIEW_TYPE_HEADER){
            viewHolder = new HearderFooterHolder(mHeaderView);
        }else if(viewType == VIEW_TYPE_FOOTER){
            viewHolder = new HearderFooterHolder(mFooterView);
        }else{//getViewHolder是抽象方法可以根据具体的子类数据类型到子类自己定义ViewHolder
            viewHolder = getViewHolder(parent);
        }
        return viewHolder;
    }


//bindView()是抽象方法,可以到具体的子类去实现
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if(getItemViewType(position) == VIEW_TYPE_NORMAL){
            bindView(holder, position, position - mHeaderCount,mBeans.get(position - mHeaderCount));
        }
    }


    @Override
    public int getItemCount() {
        return (null == mHeaderView ? 0 : 1) + mBeans.size() + (null == mFooterView ? 0 : 1);
    }


    public class HearderFooterHolder extends RecyclerView.ViewHolder{
        public HearderFooterHolder(View itemView) {
            super(itemView);
        }
    }


    protected abstract RecyclerView.ViewHolder getViewHolder(ViewGroup parent);
    protected abstract void bindView(RecyclerView.ViewHolder holder, int viewPosition, int dataIndex, T bean);


    public int getHeaderCount(){
        return  null == mHeaderView ? 0 : 1;
    }


    public int getFooterCount(){
        return null == mFooterView ? 0 : 1;
    }
}



这个基类把适配器的itemCount的计算和headerView、footerView类型的判断逻辑都已经写好了,再借用bingView和getViewHolder等抽象方法让子类去实现具体的item布局。

使我们在写具体的适配器的时候只要继承他,就可以拥有添加头部尾部和自定义item布局的功能,而不用理会复杂的计算过程。

比如,到具体的适配器时就变得很简单

public class AdapterMyGame extends BaseRecyclerViewAdapter<AppLatestInfo> {


    public AdapterMyGame(Context context, ArrayList<AppLatestInfo> mMyGame) {
        super(context, mMyGame);
    }


    @Override
    protected RecyclerView.ViewHolder getViewHolder(ViewGroup parent) {
        return new MyGame(LayoutInflater.from(mContext).inflate(R.layout.item_my_mygame, parent, false));
    }


    @Override
    protected void bindView(RecyclerView.ViewHolder holder, int viewPosition, final int dataIndex, final AppLatestInfo bean) {
        MyGame viewHolder = (MyGame) holder;
        GlideImageLoadUtils.displayImage(mContext,bean.gameIconUrl, viewHolder.mIvGameIcon, GlideImageLoadUtils.getGameIconOptions());
        viewHolder.mTvGameName.setText(mBeans.get(dataIndex).getGameName());
        final String packageName = mBeans.get(dataIndex).pkgName;
        viewHolder.mBtnStart.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                CommonHelper.openApp(mContext, packageName, bean.gameId);
            }
        });
        viewHolder.itemView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                ActivityUtils.startNormalGameDetailActivity(mContext, bean, "");
            }
        });
    }


    class MyGame extends RecyclerView.ViewHolder {
        ImageView mIvGameIcon;//游戏icon
        TextView mTvGameName;//游戏名称
        TextView mTvGameTime;//游戏时间
        TextView mBtnStart;//开始玩按钮


        public MyGame(View convertView) {
            super(convertView);
            mIvGameIcon = (ImageView) convertView.findViewById(R.id.img_my_mygame);
            mTvGameName = (TextView) convertView.findViewById(R.id.tv_gamename);
            mTvGameTime = (TextView) convertView.findViewById(R.id.tv_gametime);
            mBtnStart   = (TextView) convertView.findViewById(R.id.my_mygame_play_button);
        }
    }


}

1 0
原创粉丝点击