如何应对 Android 面试官 -> MVVM 实战一个新闻客户端 (上)

前言


本章我们基于重构的方式进行一个 MVVM 的实战,我们将一个新闻列表的普通实现,一步一步的改造成 MVVM 的架构模式,一共分为上中下三个章节;

传统方式实现


首先咱们来看具体实现的最终效果,就是一个新闻列表页面,拉取新闻标题和新闻列表;

整体页面的构建也很简单,就是 TabLayout + ViewPager + Fragment + RecyclerView + DataBinding 来搭建页面,然后通过 RxJava + Retrofit 拉取数据,并通过 adapter 展示到页面;

image.png

页面的构建并不复杂,整体的一个布局排列如上图所示;外层 Fragment 作为根 View 来包裹了一个 TabLayout 和 ViewPager 用来显示新闻标题和标题内容列表;列表以 RecyclerView 进行数据的渲染,整体实现如下:

image.png

新闻列表页面的构建也比较简单,就是 Adapter 适配两种不同类型(一种是纯文本、一种是带图片带文本)的 item,通过 ViewHolder 创建不同的布局 View;

public class NewsListRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private final int VIEW_TYPE_PICTURE_TITLE = 1;
    private final int VIEW_TYPE_TITLE = 2;
    private List<NewsListBean.Contentlist> mItems;
    private Context mContext;

    NewsListRecyclerViewAdapter(Context context) {
        mContext = context;
    }

    void setData(List<NewsListBean.Contentlist> items) {
        mItems = items;
        notifyDataSetChanged();
    }

    @Override
    public int getItemCount() {
        if (mItems != null) {
            return mItems.size();
        }
        return 0;
    }

    @Override
    public int getItemViewType(int position) {
        if (mItems != null && mItems.get(position).imageurls != null && mItems.get(position).imageurls.size() > 1) {
            return VIEW_TYPE_PICTURE_TITLE;
        }
        return VIEW_TYPE_TITLE;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view;
        if (viewType == VIEW_TYPE_PICTURE_TITLE) {
            view = LayoutInflater.from(mContext).inflate(R.layout.picture_title_view, parent, false);
            return new PictureTitleViewHolder(view);
        } else if (viewType == VIEW_TYPE_TITLE) {
            view = LayoutInflater.from(mContext).inflate(R.layout.title_view, parent, false);
            return new TitleViewHolder(view);
        }

        return null;
    }

    private class PictureTitleViewHolder extends RecyclerView.ViewHolder {
        public TextView titleTextView;
        public AppCompatImageView picutureImageView;

        public PictureTitleViewHolder(@NonNull View itemView) {
            super(itemView);
            titleTextView = itemView.findViewById(R.id.item_title);
            picutureImageView = itemView.findViewById(R.id.item_image);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    WebviewActivity.startCommonWeb(mContext, "News", v.getTag()+"");
                }
            });
        }
    }


    private class TitleViewHolder extends RecyclerView.ViewHolder {
        public TextView titleTextView;

        public TitleViewHolder(@NonNull View itemView) {
            super(itemView);
            titleTextView = itemView.findViewById(R.id.item_title);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    WebviewActivity.startCommonWeb(mContext, "News", v.getTag()+"");
                }
            });
        }
    }
    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        holder.itemView.setTag(mItems.get(position).link);
        if(holder instanceof PictureTitleViewHolder){
            ((PictureTitleViewHolder) holder).titleTextView.setText(mItems.get(position).title);
            Glide.with(holder.itemView.getContext())
                    .load(mItems.get(position).imageurls.get(0).url)
                    .transition(withCrossFade())
                    .into(((PictureTitleViewHolder) holder).picutureImageView);
        } else if(holder instanceof TitleViewHolder) {
            ((TitleViewHolder) holder).titleTextView.setText(mItems.get(position).title);
        }
    }
}

传统方式,我们会在 Adapter 中写如静态 ViewHolder,但这其实是违背六大原则中的单一职责的,我们来一步一步的拆解成 MVVM 的模式;

我们在搭建一个 App 的架构的时候,追求模块化、层次化、控件化;

控件化的意思就是自定义 View,自定义 View 有什么好处呢?可以将 ViewHolder 的创建放到这个自定义 View 中,满足了单一职责,所有 View 相关的操作都在这个自定义 View,剥离了这个 adapter,

我们先来改造 ViewHolder 的剥离;

ViewHolder 重构

我们要将 ViewHolder 从 adapter 中剥离出来,这里采用控件化的方式,将两个 ViewHolder

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值