刷新恒定片段 [英] Refreshing For Constant Fragments

查看:67
本文介绍了刷新恒定片段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将尝试描述问题并简化它在我的应用程序中,我有一个活动和3个片段,然后在电话模式"下通过它们进行交换.这些片段我在主要活动中将它们的片段实例作为常量对象,因此即使该片段不可见,与片段生命周期无关的内部对象仍保持其值(逻辑上,当破坏该片段对象时,这些对象将释放)

I will try to describe the problem and simplify it At my app, I have one activity, and 3 fragments and I swap through them at Phone Mode. and these fragments I made their fragments instances as constant objects at main activity so the internal objects which are not related to fragment life cycle stay hold their values even this fragment doesn't visible (Logically the objects will release when the fragment object is destroyed)

现在,当我尝试制作我的应用程序支持平板电脑时,我同时显示了3个片段,但是发生了一些奇怪的事情.

Now, when I tried to make my app support tablet, I made the 3 fragments display at the same time but there's something strange is happened.

说片段A的项目保留列表,片段B显示所选项目的详细信息.并且在片段B处有一个对象.此对象保存选定​​的项目ID [所有片段在一个活动中同时显示,如我之前提到的那样],此对象在创建片段B时保存当前项目ID值,并保存新的ID在片段B调用 onDestroyView()方法时选择的项目ID.

Say fragment A hold list of items and fragment B show the detail of selected item. and there is an object at fragment B. this object holds the selected item id [All fragments display at the same time in one activity as I mentioned before], this object save current item id value when the fragment B created, and save the new selected item id when onDestroyView() method called at fragment B.

现在,当我启动我的应用程序时,我添加了片段A,并且当我从列表中选择项时,片段B被添加了,并且其对象保留了所选的值.现在一切都对了.当我选择另一个项目时,我只需要刷新片段B,因为内部对象将保存新选择的ID,所以我做了这行

Now, when I start my app, I add the fragment A, and when I select item from list the fragment B is added and its object hold the selected value. for now all things are right. when I select another item, I just need to refresh the fragment B as the internal object will hold the new selected id so I did this line

 Fragment fragment = mFragmentManager.findFragmentByTag([fragmentId]);
 mFragmentManager.beginTransaction().detach(fragment).attach(fragment).commit();

但是我得到的结果是片段B获得了它所处的先前状态,我的意思是内部对象保存了我选择的第一个项目ID.

but the result I got is that the fragment B get the previous state which it was on, what I mean is that the internal object hold the first item id i selected.

我试图在刷新片段之前测试内部对象

I tried to test the internal object before fragment refreshing

 Fragment fragment = mFragmentManager.findFragmentByTag([fragmentId]);
 Log.e("my object","value" + String.valueOf(fragment.getValue));
 mFragmentManager.beginTransaction().detach(fragment).attach(fragment).commit();

并且它持有正确的项目ID值,该值必须显示...!另外,我通过传递常数值来确保,但得到相同的奇怪结果

and It was holding the right item id value which have to display ... !! Also I passed the constant value instead to ensure but I get the same strange result

 Fragment fragment = mFragmentManager.findFragmentByTag([fragmentId]);
 mFragmentManager.beginTransaction().detach(fragment).attach(FRAGMENT).commit();

那么怎么回事?从逻辑上讲,它必须按照我的想法工作.

So what's happen ?? Logically it have to work as I think.

pic表示原始代码这是日志结果(注意:2是我选择的下一项)这是刷新片段B后的下一个日志结果(请注意,片段B内的该日志且id 3是我选择的第一个项),预期结果为2

pic for the original code and this is the log result (Note: 2 is the next item i selected) and this is the next log result after fragment B is refreshed (Note this log inside fragment B and id 3 is the first Item i selected) the expected result is 2

推荐答案

最后,我了解了片段事务行为及其工作原理...

Finally I understood the fragment transaction behavior and how it works ...

一旦您将新片段添加/替换为 Fragment Transaction ,您的对象就会保存为 Fragment Manager 中的初始状态,并且当您尝试分离片段并重新连接时[相同object], Fragment Manager 将获得您之前将其传递给 add()/ replace()函数的对象状态.这就是我得到结果的原因.

Once you add/replace new fragment to Fragment Transaction you object is saved as initial state within Fragment Manager and when you try to detach the fragment and reattach [the same object] the Fragment Manager will get the object state which you passed it before to add()/replace() function. So that's the reason of the result I got.

为简化起见.

  • 假设您有一个A类,它是从 Fragment 类扩展的,并且该类包含 Integer 对象没有任何值,并且具有 Set()/ Get()方法.

  • Suppose that you have an Class A extends from Fragment class and this class contains Integer object have no value and have Set()/Get() methods.

现在从此类A创建一个实例,并调用 Set()函数并将值1传递给它.然后通过 add()/replace()`方法将此实例传递给 Manager Transaction .

Now create an instance from this Class A and call Set() function and pass value 1 to it. Then pass this instance to Manager Transaction by add()/replace()` method.

现在尝试调用 Set()函数并将 Integer 对象更改为另一个值.

Now try to call Set() function and change the Integer object to another value.

分离类A并重新附加它并检查该对象的值,您将获得对象的值返回给您分配的初始值,然后再将该对象传递给 Manger Transaction

Detach the class A and reattach it and check the value of this object, you will get that the value of object return to initial value you assigned before passing the object to Manger Transaction

此外,还有一个重要说明... 片段事务 add() replace() remove()... 在主线程上不起作用,这就是使用 commit()方法和 commitNow()方法..的原因,因为当您使用 commit()您的操作将添加到 Fragment Transaction 队列中,因此它将在一段时间后执行,但现在不是按队列中的顺序执行,因此您还有另一个名为 commitNow()的方法可以使您的操作立即执行.

Beside that there's an important note ... Fragment Transaction Actions like add(), replace(), remove() ... don't work at main thread and that's the reason of using commit() method and commitNow() method .. because when you use commit() your action will add to Fragment Transaction Queue so it will be executed after a bit of time but not now that's upon its order inside the queue, and so that you have another method called commitNow() to make your action execute immediately.

这篇关于刷新恒定片段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆