MVVM与DataBinding简单使用

                                MVVM与DataBinding简单案例

一、MVVM

1.MVVM是什么

MVVM(Model–View–Viewmodel)是一种软件架构模式。

M----->Model层:请求的原始数据

V----->View层:视图展示,由ViewController来控制

VM---->ViewModel层:负责业务处理和数据转化

MVVM与MVC的不同

首先我们简化一下MVC的架构模式图:

在这里插入图片描述

在这里,Controller需要做太多得事情,表示逻辑、业务逻辑,所以代码量非常的大。而MVVM:

在这里插入图片描述

在MVVM中,我们趋向于将view和view controller作为一个整体(这也解释了为什么不称它为MVVCVM),新的viewModel代替原来的viewController协调view与model之间的交互。

2.基本使用

创建好一个Android Project之后,在gradle文件中添加如下几行代码,表示开启databinding:

android {
    ...

    dataBinding{

        enabled true

    }
    ...
}

3.以两个功能案例举例areacode(地区和区号)和topimage(图片加载)

二、areacode(地区和区号)

1.页面布局

2.主要model

3.VM:AreaCodeViewModel

3.activity

4.显示效果

三、topimage(图片加载),添加RecyclerView展示数据列表

1.布局文件

2.主要model

3.VM之TopImageViewModel

public class TopImageViewModel {

    private List<ImgInfoModel> listImage = new ArrayList<>();
    private List<ImgInfoModel> listImage_refresh = new ArrayList<>();
    private DataBindingRecyclerViewAdapter adapter;

    public TopImageViewModel(final TopImageActivity activity) {
        OkHttpClient client = new OkHttpClient();//创建OkHttpClient对象
        FormBody.Builder forBody1 = new FormBody.Builder();//创建表单请求体
        forBody1.add("LANGUAGE", String.valueOf(0));//传递键值对参数
        forBody1.add("CURR", "RMB");//传递键值对参数
        forBody1.add("NO_DEVICE", String.valueOf(1));//传递键值对参数

        FormBody.Builder forBody = new FormBody.Builder();//创建表单请求体
        forBody.add("COMMONINFO", String.valueOf(forBody1));//传递键值对参数
        forBody.add("TOKENINFO", "");//传递键值对参数
        forBody.add("VIPCONTENT", "");//传递键值对参数
        Request request = new Request.Builder()//创建Request 对象
                .url("https://xxxxxxxxxxxxxxx")//接口
                .post(forBody.build())//传递请求体
                .build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                Log.d("kwwl", "获取数据失败----");
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
//                Log.d("kwwl", "获取数据成功了----");
//                Log.d("kwwl", "response.code()---==" + response.code());
//                Log.d("kwwl", "response.body().string()---==" + response.body().string());
                RImgInfoModel model = new Gson().fromJson(response.body().string(), RImgInfoModel.class);
                if (model.getRESULTCODE().getVIPCODE() == 0) {
                    listImage.addAll(model.getVIPCONTENT());
                    listImage_refresh.addAll(listImage);
                    //Only the original thread that created a view hierarchy can touch its views
                    //翻译过来:只有创建这个view的线程才能操作这个view

                    //在使用Volley的时候这个问题就不怎么会遇到了,那是因为无论是HttpURLConnection还是OkHttp
                    //最终的回调接口,即onResponse运行在子线程
                    //所以一旦在回调接口对UI进行了操作,将会出现上述提示
                    //一般来讲,会使用handle解决这个问题
                    activity.runOnUiThread(new Runnable() {
                        public void run() {
                            adapter = new DataBindingRecyclerViewAdapter(activity, R.layout.item_image, com.dawn.mvvmanddatabinding.BR.imgItem, listImage);
                            activity.binding.recyclerView.setLayoutManager(new LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false));
                            activity.binding.recyclerView.setAdapter(adapter);

                            adapter.setOnItemCkickListener(new DataBindingRecyclerViewAdapter.ItemClickListener() {
                                @Override
                                public void itemClick(View view, int position) {
                                    Log.e("111",listImage.get(position).getST_IMGENGNAME()+"---");
                                    Toast.makeText(activity, listImage.get(position).getST_IMGPATH()+"----"+position, Toast.LENGTH_LONG).show();
                                }
                            });
                        }
                    });
                } else
                    Log.d("kwwl", model.getRESULTCODE().getVIPINFO() + "================");
            }
        });
    }

    public void refresh() {
        listImage.clear();
        if (listImage_refresh.size() != 0)
            listImage.addAll(listImage_refresh);
        adapter.notifyDataSetChanged();
    }

    public void remove() {
        if (listImage.size() != 0)
            listImage.remove(0);
        adapter.notifyDataSetChanged();
    }

    public void add() {
        ImgInfoModel p = new ImgInfoModel();
        p.setST_IMGENGNAME("我爱吃水果  --新增的图片");
        p.setST_IMGPATH("https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1302960203,381285259&fm=26&gp=0.jpg");
        listImage.add(0, p);
        adapter.notifyDataSetChanged();
    }
}

4.适配器布局

5.适配器代码

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

    Context mContext;
    int mLayoutId;
    int mVarId;
    private List mData;
    public static final int TYPE_HEADER = 1, TYPE_FOOTER = 2, TYPE_NORMAL = 0;
    boolean haveHeader = false;
    boolean haveFooter = false;
    View headerView, footerView;
    private ItemClickListener itemClickListener;
    public OnBindingViewHolderListener onBindingViewHolderListener;

    public DataBindingRecyclerViewAdapter(Context context, int layoutId, int varId, List data) {
        mContext = context;
        mLayoutId = layoutId;
        mVarId = varId;
        mData = data;
    }

    public void setOnItemCkickListener(ItemClickListener listener) {
        this.itemClickListener = listener;
    }

    public void setOnBindingViewHolderListener(OnBindingViewHolderListener listener) {
        onBindingViewHolderListener = listener;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType) {
            case TYPE_HEADER:
                return new ViewHolder(headerView, viewType);
            case TYPE_FOOTER:
                return new ViewHolder(footerView, viewType);
            case TYPE_NORMAL:
                return new ViewHolder(LayoutInflater.from(mContext).inflate(mLayoutId, parent, false), viewType);
            default:
                return new ViewHolder(LayoutInflater.from(mContext).inflate(mLayoutId, parent, false), viewType);
        }
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {
        switch (holder.viewType) {
            case TYPE_HEADER:
                break;
            case TYPE_FOOTER:
                break;
            case TYPE_NORMAL:
            default:
                ViewDataBinding binding = DataBindingUtil.bind(holder.itemView);
                Object data;
                if (haveHeader) {
                    data = mData.get(position - 1);
                } else {
                    data = mData.get(position);
                }

                if (itemClickListener != null) {
                    holder.itemView.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            itemClickListener.itemClick(holder.itemView, position);
                        }
                    });
                }

                binding.setVariable(mVarId,data);
                binding.executePendingBindings();
                if (onBindingViewHolderListener != null) {
                    onBindingViewHolderListener.onHolderBinding(holder, position);
                }
                break;
        }
    }

    /**
     * 调用之后请调用NotifyDataSetChange 如果在setAdapter之后
     *
     * @param view
     */
    public void addFooterView(View view) {
        haveFooter = true;
        footerView = view;
    }

    /**
     * 调用之后请调用NotifyDataSetChange 如果在setAdapter之后
     *
     * @param view
     */
    public void addHeaderView(View view) {
        haveHeader = true;
        headerView = view;
    }

    public void removeFooterView() {
        footerView = null;
        haveFooter = false;
    }

    public View getFooterView() {
        return footerView;
    }

    public void cleanData() {
        mData.clear();
        notifyDataSetChanged();
    }

    public List getAllData() {
        return mData;
    }

    public void addData(List data) {
        mData.addAll(data);
        notifyDataSetChanged();
    }

    @Override
    public int getItemCount() {
        int extraCount = 0;
        if (haveHeader) {
            extraCount++;
        } else if (haveFooter) {
            extraCount++;
        }
        return mData.size() + extraCount;
    }

    @Override
    public int getItemViewType(int position) {
        if (position == 0 && haveHeader) {
            return TYPE_HEADER;
        } else if (position == mData.size() && haveFooter) {
            return TYPE_FOOTER;
        } else {
            return TYPE_NORMAL;
        }
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        int viewType;

        public ViewHolder(View itemView, int viewType) {
            super(itemView);
            this.viewType = viewType;
        }
    }

    public interface ItemClickListener {
        void itemClick(View view, int position);
    }

    public interface OnBindingViewHolderListener {
        void onHolderBinding(ViewHolder holder, int position);
    }
}

6.加载适配器图片代码

7.activity代码

8.效果图

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值