Day 29 - [Android APP] 07-MVVM中的RecyclerView与Adapter

铁人赛快到尾声了,今天想介绍在控制 RecyclerView 中回馈按钮时,遇到的状况。想想,这篇好像应该和前一篇顺序对调,毕竟是先有这些纠结,才有後面自己归纳出的那些写法。所以先暂时忘掉昨天的写法,回到 MVVM 的初学者吧。

大家觉得 Adapter 应该属於 View 层或是 ViewModel 层呢?

第一次写 MVVM 搭配 RecyclerView,突然不知道要怎麽用,爬了网路上的文章後,却又更更更混乱了。
可以先看一下这两篇:

Adapter 的归类

取自第一篇的整理,网路上的写法大致上有三种

  1. VM 持有 Adapter
  2. V持有Adapter,但每次资料更新都重建Adapter
  3. V持有Adapter,但每次都 notifyDataSetChanged()

我後来又爬了多文章和范例,也和朋友讨论过,还是觉得 Adapter 负责资料的显示应该属於 View,而我实作的方法偏第 2 种。下面附上我的程序码:

完整版程序码: https://gitlab.com/graduate_lab415/chatbot/-/blob/master/app/src/main/java/com/cmrdb/app/chatbot/view/ChatActivity.java

private final Observer<ArrayList<Chat>> mChatListUpdateObserver = new Observer<ArrayList<Chat>>() {
    @Override
    public void onChanged(ArrayList<Chat> chatArrayList) {
        OptionClickCallback optionClickCallback = new OptionClickCallback() {
            @Override
            public void onOptionClick(Option option) {
                mViewModel.sendOptionMessage(option, categoryId);
            }

            @Override
            public void noneOfAbove(Option option) {
                mViewModel.sendOptionMessage(option, categoryId);
            }
        };
        ChatAdapter mChatAdapter = new ChatAdapter(ChatActivity.this, chatArrayList, optionClickCallback);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(ChatActivity.this));
        mRecyclerView.setAdapter(mChatAdapter);
        mRecyclerView.scrollToPosition(mChatAdapter.getItemCount() - 1);
        mProgressLayout.setVisibility(View.GONE);
    }
};

我是在聊天纪录的 Observer 里,只要聊天纪录有变动,就重新生成 Adapter 和提供更新後的聊天纪录。

Adapter 和 ViewModel 的互动

既然已经决定 Adapter 属於 View,我遇到的第二个问题是当 Adapter 要怎麽和 ViewModel 互动?

我的案例是回馈按钮被点击後,需要使用 ChatViewModel 中的 sendOptionMessage(),要怎麽呼叫呢?

  1. Activity 透过 Adapter 的建构子,将 Viewmodel 物件传入。在 Adapter 中处理监听事件,并使用传入的 ViewModel 物件。
  2. 在 Adapter 中建立一个 ViewModel 物件,一切由 Adapter 自己操作 (这作法我没试过,不确定会不会有什麽问题)
  3. 维持 ViewModel 的物件只有一个,且由 Activity 操作。让被点击的事件,回归到 Activity 处理。

我不确定第一种作法,将 ViewModel 当参数传来传去好不好,不过我自己不是很喜欢。所以,後来是选用第 3 种方式。

这个问题,我也不确定作法好不好,如果你有什麽想法欢迎留言讨论哦!!



<<:  [DAY 30] _韧体学习路程经验谈

>>:  [day28]优化架构-订单留存及检核(1)

day5_Windows,Linux, MacOs 与 arm 的支援度和 x86 的差异

三大作业系统 目前无论是桌上型电脑与笔记型电脑抑或是服务器,大致上可分为三个主要作业系统,Windo...

Day 21. Zabbix 自动化通知介绍

首先在介绍自动化通知之前,需要介绍是如何被触发的。 触发器的设定也是跟着套用样板时候被设定。 具体可...

Methods to Login to Your ATT Account

To be honest, the ATT login process is not as comp...

[WMX3] 8.IO - GetInBytes

Input需要接上实体模组才能读取状态。 使用方法 //新增 public static int I...

App Inventor 学习笔记 3 : 读取csv档

这篇是测试如何读取csv档, csv table转入list会以2维方式记录, 操作重点还是list...