场景
在往常项目开发中,经常会遇到一个布局在整个项目中会呈现很屡次的状况。这时分,咱们就需求将这个布局拖出来,作为一个子布局,在需求运用的当地经过标签复用。
问题
在数据双向绑定中,假如一个子布局要想通用,又有必要坚持数据双向绑定的功用,运用ViewModel的时分,在子布局和界面中运用的时分,就会遇到,无法坚持子布局数据的唯一性(也便是同一个子布局,在同一个界面中运用的时分,假如这个这个界面屡次这个子布局)
问题中的代码
主界面xml
处理进程
本来在这儿是要写处理进程的进程,这样能够给大家一些处理问题的启发。不过这次处理的进程比较久,也比较复杂。鉴于自己是个小菜鸟的缘故,所以这次就不写具体的进程了。
简略的描述一下处理的进程
开始的时分,我拿着 ViewModel include关键词,在百度、必应、谷歌、stackoverflow等网站都搜了一下,看了很多的文章【在这儿吐槽一下,stackoverflow网站,我真的不会搜东西,用关键词查的时分,我总是没找到需求的,可能stackoverflow上的答案和我无缘吧,不过我仍是喜欢在无助的时分,来找找,也许就给我找到答案了呢】
在这儿我找到了有用的东西,感谢大佬的分享,可是这儿并没有回答我的问题。
后来我又屡次的在网上找答案,仍然没有找到
然后我只能去找大佬们了
大佬们拿着ChatGPT,给我查找,哈哈哈,启发了我,我也用YouChat查找着,成果奈何表达不到位,成果不理想啊,真的很想把整个项目丢给ChatGPT,告诉我这个怎么做吧(哈哈哈)
后边跟着另一个大佬一同,一边测试,一遍考虑,才最终得到了自己想要的答案
在处理问题的前期
遇到的一个问题【以下图片的报错】
问题原因是我在主xml内给子布局赋值ViewModel的数据的时分,没有依据子布局设定的ViewModel的变量名来命名,两个名字要改成相同的就能够了。
改后
继续处理问题
前期的时分在想,子布局也运用ViewModel,所以,我给子布局添加了ViewModel,并在主布局的ViewModel中测验新建子布局的ViewModel,如下:
这个方法会遇到一个问题,运用了同一个MvvmModel作为子布局的ViewModel;这时分要追究到ViewModel的创立时分了。
这个是两个不同的ViewModel,是没有问题的
可是
检查创立ViewModel的进程,能够发现是依据类名作为key的,所以这时分两个子布局都是运用MvvmModel,就会呈现数据相同的状况。
咱们在往常开发中,肯定是运用不同的数据显现,这时分,你假如改成两个不同的ViewModel,那么也就意味着,你有必要写两个不同的子布局,那就起不到子布局复用的状况。
欢迎来到最终的处理方案,在此之前,先插个另一个没有报错的错误
界面无法显现ViewModel的数据
日志打印了修正后的数据,可是界面上一直是初始化的数据,真的很爪机
后来检查了笔记(我在有道的笔记,这个现已好久没翻开了,我一直记住有做过这个,可是在飞书上没有搜到,只好翻开有道了,然后真的找到了),才找到原因的
这个笔记,注释是在fragment的时分运用的,可是我记住这句话,用上了,数据成功显现了,这口气总算通了真爽(哈哈哈哈)
展示一下数据改变后的界面
这个按钮是之前判别会不会由于是handler来触发引起的界面不能显现的问题,将handler的触发改成了按钮的事件,还有线程,后边成功了之后发现这3个都能完成界面数据的改变的。
真的来到最终了
处理办法
直接上图了
子布局的ViewModel修正成了运用根本数据类型
别只看到界面里的String,是根本数据类型,这样你能够在主界面的ViewModel内运用一个变量来控制子布局
这样,在任何时分,子布局都能通用,也不会产生在同一个界面的屡次include的时分,同个inclde的子布局数据一同改变
那么大佬又问了,那我在子布局里有多个的TextView(大佬在举栗子哈,别笑),这个就简略了
看吧这个比如很简略,一下秒懂,有没有;便是在data标签里搞动作,记住在主界面调用的时分也要动一下,别偷闲,具体主界面的xml怎么动,前面现已有说过了,认真看的朋友现已有了答案了
好了,这次的问题处理现已有了答案,总算能够高兴的运用MVVM了,没有双向绑定的MVVM,我觉得失去魂灵,在处理问题进程中还看了一个说是MVVM框架的项目,以为会有数据双向绑定的,成果根本就没有,挺郁闷的
最终感谢各位大佬的帮助,鲜花献花~~~
哇哈哈哈哈,完毕
追续【2023.3.2】
运用实体目标来代替基础类型,在字不居中运用
不运用基础类在子布局中运用
改用实体目标【这儿的实体目标是没有承继ViewModel,假如承继了,便是前面说的状况】
在子布局中运用实体目标
在父布局中运用
改变实体目标的内容
成果:修正成功
可是,假如运用以下方法修正视图目标的数据,就无法收效【这儿的setValue是由于内部特点是value,才会有这个set方法】
只能每次都是从头设置一个新的目标