V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ppg01065
V2EX  ›  Android

jetpack 实践时的疑问,比较复杂的页面 Livedata 要怎么用才好?

  •  
  •   ppg01065 · 2020-05-30 17:58:48 +08:00 · 9945 次点击
    这是一个创建于 1669 天前的主题,其中的信息可能已经有所发展或是发生改变。

    这里指的复杂主要是表单要填的内容很多,再加上多个字段都需要联动的情况下怎么才算是比较好的写法?

    项目接近于 OA 办公类的 app 。某些页面要填写编辑表单,一个表单常常有 20-30 个可编辑项

    假设 FormBean 这个实体类对应的表单对象 UserForm 有 30 个字段。每个字段都能编辑

    那么如果我在页面上只对 Name 字段进行修改的话,怎么更新 UserForm 并且触发 LiveData 的 onChanged 事件呢?

    目前在网上的文章 Livedata 都是用 MutableLiveData<String>之类的基本类型做例子,没找到怎么更新某个具体的实体类的方式

    public class MainViewModel extends ViewModel {
        /*
        公司的项目接近 OA 办公类产品,有很多表单需要填写和修改
        假设这个 FormBean 表单对象有 30 个字段。每个字段都能编辑,如果每个字段都单独创建一个 livedata 对象的话,会变成很长的代码
        private MutableLiveData<String> field1;
        private MutableLiveData<String> field2;
        private MutableLiveData<String> field3;
        private MutableLiveData<String> field4;
        private MutableLiveData<String> field5;
        ........
        private MutableLiveData<String> field29;
        private MutableLiveData<String> field30;
        
        然后每个字段都要写 get 和 set 方法。每个字段都要设置 observe 监听,这样的代码算是最佳实践吗?感觉要写很多重复代码。
        */
    
        //如果只创建一个 FormBean 的实体类,可以只设置一次 observe 监听,但是要怎么更新其中的某一个字段呢?
        private MutableLiveData<FormBean> UserForm;
    
        public LiveData<FormBean> getCurrentUserForm() {
            if (UserForm == null) {
                UserForm = new MutableLiveData<FormBean>();
                FormBean formBean = new FormBean();
                formBean.setName("aaabbb");
                formBean.setId(123);
                UserForm.setValue(formBean);
            }
            return UserForm;
        }
    
        public void setField1(String userName) {
            //我目前想的方法是在 set 方法里先通关 getValue()获取 livedata 持有的实体类,更新对应的字段后再重新 setValue 回去。我不知道这算不算好办法,但是暂时想不出其他办法了
            UserForm.getValue().setName(userName);
            UserForm.setValue(UserForm.getValue());
        }
    }
    

    我目前觉得我的写法有点过于浪费,因为这样写就算只更新一个 Name 字段也会使得所有观察了 UserForm 的控件刷新一次。

    有没有兄弟可以告诉我这种情况怎么办,或者给一个思路。

    昨天看了一天的 github,大部分用了 jetpack 的示例都是获取数据 ---》 展示数据。最多就修改一个 id 之类的。很简洁也很漂亮。但是我发现我如果要照这样写,我就能在页面上写出 30 个 MutableLiveData<String> field1 了。

    12 条回复    2020-06-12 13:52:54 +08:00
    sankemao
        1
    sankemao  
       2020-05-30 21:18:49 +08:00
    可以用 livedata 在 xml 里面双向绑定
    https://developer.android.com/topic/libraries/data-binding/two-way
    ppg01065
        2
    ppg01065  
    OP
       2020-05-30 21:24:39 +08:00
    @sankemao 只能用 DataBinding 吗?目前只想用 ViewBinding,感觉 DataBinding 不香。。
    ppg01065
        3
    ppg01065  
    OP
       2020-05-30 21:26:13 +08:00
    而且表单里面的很多数据都是有一定的联动变化要求,所以更新在代码中处理数据
    winterbells
        4
    winterbells  
       2020-05-30 22:34:13 +08:00 via Android
    databinding 啊
    viewbinding 我记得文档说不支持数据双向绑定的吧

    UI model 单独一个类,在 viewmodel 里声明,都放 viewmodel 太乱了。。



    可以参考我写的这个,可能不是太好的解决方案,但上家比较大的应用也是按这个来的
    https://github.com/ohyooo/MVVMBaseProject
    ppg01065
        5
    ppg01065  
    OP
       2020-05-30 23:04:42 +08:00
    @winterbells 目前是不打算用双向绑定,才用的 viewbinding 。所以一直在寻找解决的思路
    GuilinLR
        6
    GuilinLR  
       2020-06-01 10:23:50 +08:00
    @ppg01065 databinding 香的狠,打个比方,自己写个 adapter,设置控件的隐藏动画,都不用动 java 代码。还有其他一些妙用。
    fromzero
        7
    fromzero  
       2020-06-01 22:35:36 +08:00 via Android
    把表单的数据尽量合并成一个类,或者按分类合并成几个类。20 30 个可编辑项按功能抽成几个类
    fromzero
        8
    fromzero  
       2020-06-01 22:38:16 +08:00 via Android
    用 kotlin 的话,字段改动,就直接 livedata.value = data.copy
    sukaidev
        9
    sukaidev  
       2020-06-02 12:34:31 +08:00
    用 databinding 双向绑定是最优雅的
    longyuan5
        10
    longyuan5  
       2020-06-12 09:27:16 +08:00 via Android
    Databinding 优雅啥呀,还要去 xml 写逻辑,没搞懂优雅什么?
    longyuan5
        11
    longyuan5  
       2020-06-12 09:28:22 +08:00 via Android
    在 activity 写怎么就不优雅?没搞懂一帮人自嗨啥
    colaman
        12
    colaman  
       2020-06-12 13:52:54 +08:00
    @longyuan5 照人家的逻辑,几十个输入框要编辑,你在 activity 得写多少代码? databinding 是原罪? 在这里直接一个双向绑定更新实体类数据难道有什么问题? 连官网都是建议 viewbinding 和 databinding 一起使用。你在这一句在 xml 里写代码不优雅就把 databinding 给否决掉了?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5370 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 08:38 · PVG 16:38 · LAX 00:38 · JFK 03:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.