刷新常量片段
Refreshing For Constant Fragments
我会尽量描述问题并简化它
在我的应用程序中,我有一个 activity 和 3 个片段,我在 Phone 模式下交换它们。这些片段我将它们的片段实例作为 main activity 中的常量对象,因此与片段生命周期无关的内部对象保持它们的值,即使这个片段不可见(逻辑上对象将在片段时释放对象被销毁)
现在,当我尝试让我的应用程序支持平板电脑时,我同时显示了 3 个片段,但发生了一些奇怪的事情。
假设片段 A 包含项目列表,片段 B 显示 selected 项目的详细信息。片段 B 处有一个对象。此对象保存 selected 项目 ID [所有片段同时显示在一个 activity 中,如前所述],此对象保存当前项目 ID 值时片段 B 创建,并在片段 B 调用 onDestroyView()
方法时保存新的 selected 项目 ID。
现在,当我启动我的应用程序时,我添加片段 A,当我从列表中添加 select 项时,片段 B 被添加并且其对象持有 selected 值。现在一切都很好。
当我 select 另一个项目时,我只需要刷新片段 B 因为内部对象将保存新的 selected id 所以我做了这一行
Fragment fragment = mFragmentManager.findFragmentByTag([fragmentId]);
mFragmentManager.beginTransaction().detach(fragment).attach(fragment).commit();
但我得到的结果是片段 B 获得了它之前的状态,我的意思是内部对象持有第一个项目 ID i selected.
我尝试在片段刷新前测试内部对象
Fragment fragment = mFragmentManager.findFragmentByTag([fragmentId]);
Log.e("my object","value" + String.valueOf(fragment.getValue));
mFragmentManager.beginTransaction().detach(fragment).attach(fragment).commit();
并且它持有必须显示的正确项目 ID 值...!!
我也传递了常量值来确保但我得到了同样奇怪的结果
Fragment fragment = mFragmentManager.findFragmentByTag([fragmentId]);
mFragmentManager.beginTransaction().detach(fragment).attach(FRAGMENT).commit();
所以发生了什么??
逻辑上它必须像我想的那样工作。
图片为原码
这是日志结果(注意:2 是我 selected 的下一项)
这是刷新片段 B 后的下一个日志结果(注意片段 B 中的此日志,id 3 是第一个项目 i selected)预期结果是 2
我终于理解了片段事务行为及其工作原理...
一旦你 add/replace 新片段到 Fragment Transaction
你的对象被保存为 Fragment Manager
中的初始状态并且当你尝试分离片段并重新附加 [同一对象] Fragment Manager
将获取您之前传递给 add()
/replace()
函数的对象状态。
这就是我得到结果的原因。
为了简化它。
假设你有一个 Class A extends from Fragment
class 并且这个 class contains Integer
object have no value并有 Set()
/Get()
方法。
现在从这个 Class A 创建一个实例并调用 Set()
函数并将值 1 传递给它。然后通过 add()
/replace()` 方法将此实例传递给 Manager Transaction
。
现在尝试调用 Set()
函数并将 Integer
对象更改为另一个值。
分离 class A 并重新附加它并检查此对象的值,您将得到对象 return 的值到您在传递之前分配的初始值反对 Manger Transaction
除此之外还有一个重要说明... Fragment Transaction
add()
、replace()
、remove() ...
等操作在主线程中不起作用,这就是使用 commit()
方法和 commitNow()
方法 .. 因为当您使用 commit()
时,您的操作将添加到 Fragment Transaction
队列中,因此它会在一段时间后执行,但不是现在根据其在队列中的顺序,这样您就有了另一个名为 commitNow()
的方法来使您的操作立即执行。
我会尽量描述问题并简化它 在我的应用程序中,我有一个 activity 和 3 个片段,我在 Phone 模式下交换它们。这些片段我将它们的片段实例作为 main activity 中的常量对象,因此与片段生命周期无关的内部对象保持它们的值,即使这个片段不可见(逻辑上对象将在片段时释放对象被销毁)
现在,当我尝试让我的应用程序支持平板电脑时,我同时显示了 3 个片段,但发生了一些奇怪的事情。
假设片段 A 包含项目列表,片段 B 显示 selected 项目的详细信息。片段 B 处有一个对象。此对象保存 selected 项目 ID [所有片段同时显示在一个 activity 中,如前所述],此对象保存当前项目 ID 值时片段 B 创建,并在片段 B 调用 onDestroyView()
方法时保存新的 selected 项目 ID。
现在,当我启动我的应用程序时,我添加片段 A,当我从列表中添加 select 项时,片段 B 被添加并且其对象持有 selected 值。现在一切都很好。 当我 select 另一个项目时,我只需要刷新片段 B 因为内部对象将保存新的 selected id 所以我做了这一行
Fragment fragment = mFragmentManager.findFragmentByTag([fragmentId]);
mFragmentManager.beginTransaction().detach(fragment).attach(fragment).commit();
但我得到的结果是片段 B 获得了它之前的状态,我的意思是内部对象持有第一个项目 ID i selected.
我尝试在片段刷新前测试内部对象
Fragment fragment = mFragmentManager.findFragmentByTag([fragmentId]);
Log.e("my object","value" + String.valueOf(fragment.getValue));
mFragmentManager.beginTransaction().detach(fragment).attach(fragment).commit();
并且它持有必须显示的正确项目 ID 值...!! 我也传递了常量值来确保但我得到了同样奇怪的结果
Fragment fragment = mFragmentManager.findFragmentByTag([fragmentId]);
mFragmentManager.beginTransaction().detach(fragment).attach(FRAGMENT).commit();
所以发生了什么?? 逻辑上它必须像我想的那样工作。
图片为原码 这是日志结果(注意:2 是我 selected 的下一项) 这是刷新片段 B 后的下一个日志结果(注意片段 B 中的此日志,id 3 是第一个项目 i selected)预期结果是 2
我终于理解了片段事务行为及其工作原理...
一旦你 add/replace 新片段到 Fragment Transaction
你的对象被保存为 Fragment Manager
中的初始状态并且当你尝试分离片段并重新附加 [同一对象] Fragment Manager
将获取您之前传递给 add()
/replace()
函数的对象状态。
这就是我得到结果的原因。
为了简化它。
假设你有一个 Class A extends from
Fragment
class 并且这个 class containsInteger
object have no value并有Set()
/Get()
方法。现在从这个 Class A 创建一个实例并调用
Set()
函数并将值 1 传递给它。然后通过add()
/replace()` 方法将此实例传递给Manager Transaction
。现在尝试调用
Set()
函数并将Integer
对象更改为另一个值。分离 class A 并重新附加它并检查此对象的值,您将得到对象 return 的值到您在传递之前分配的初始值反对
Manger Transaction
除此之外还有一个重要说明... Fragment Transaction
add()
、replace()
、remove() ...
等操作在主线程中不起作用,这就是使用 commit()
方法和 commitNow()
方法 .. 因为当您使用 commit()
时,您的操作将添加到 Fragment Transaction
队列中,因此它会在一段时间后执行,但不是现在根据其在队列中的顺序,这样您就有了另一个名为 commitNow()
的方法来使您的操作立即执行。