片段已激活 - 尝试 setArguments 时
Posted
技术标签:
【中文标题】片段已激活 - 尝试 setArguments 时【英文标题】:Fragment already active - When trying to setArguments 【发布时间】:2013-11-28 17:36:25 【问题描述】:我正在使用下面链接中给出的示例
http://android-er.blogspot.in/2013/04/handle-onlistitemclick-of-listfragment.html
这里我有两个类,一个扩展 List Fragment,另一个扩展 Fragment。 现在我以这种方式将对象传递给detailfragment:
*来自 ListFragment *
@Override
public void onListItemClick(ListView l, View v, int position, long id)
Detailfragment detailFragment = (Detailfragment)getFragmentManager().findFragmentById(detailFragmentID);
Bundle bundle = new Bundle();
bundle.putSerializable(BUNDLE_KEY, obj);// passing this object
detailFragment.setArguments(bundle);
detailFragment.setUpLayout();// update the UI
现在在 Fragment 类中我收到它,基本目标是根据列表片段中选择的项目更新片段的 UI,这就是我发送对象的原因
Bundle b = getArguments();
b.getSerializable(BUNDLE_KEY);
现在在选定的项目上显示“片段已激活”。
这里有什么问题?我做错了什么?
【问题讨论】:
【参考方案1】:另一种解决方案是为您的片段创建一个空的构造函数。
public Detailfragment()
super();
// Just to be an empty Bundle. You can use this later with getArguments().set...
setArguments(new Bundle());
并在 onListItemClick 方法中使用该捆绑包:
@Override
public void onListItemClick(ListView l, View v, int position, long id)
Detailfragment detailFragment = (Detailfragment)getFragmentManager().findFragmentById(detailFragmentID);
// Update the keys.
detailFragment.getArguments().putSerializable(BUNDLE_KEY, obj);// passing this object
detailFragment.setUpLayout();// update the UI
现在您可以在 setUpLayout() 方法中调用 getArguments() 方法。
【讨论】:
这实际上是一个好主意,我使用了它的突变作为解决方案。此外,这应该设置为正确答案,因为解决方案围绕 getArguments() 及其操作 - 与第一个答案不同,它是一种不适合 所有 场景的解决方法。 我没有看到Fragment
有一个名为 setupLayout()
的方法【参考方案2】:
来自官方 Android 开发参考:
public void setArguments (Bundle args) 提供此片段的构造参数。这只能在片段附加到其活动之前调用;也就是说,您应该在构建片段后立即调用它。此处提供的参数将在片段销毁和创建过程中保留。
您的片段已附加到其活动中 我建议你使用你自己的方法,你不需要setArguments!
在片段类中创建自己的 setUIArguments(Bundle args) 并在此方法中更新片段 UI
你会这样调用这个方法:
@Override
public void onListItemClick(ListView l, View v, int position, long id)
Detailfragment detailFragment = (Detailfragment)getFragmentManager().findFragmentById(detailFragmentID);
Bundle bundle = new Bundle();
bundle.putSerializable(BUNDLE_KEY, obj);// passing this object
detailFragment.setUIArguments(bundle); /* your new method */
在您的片段类中
public void setUIArguments(Bundle args)
getActivity().runOnUiThread(new Runnable()
public void run()
/* do your UI stuffs */
【讨论】:
我的类在像这个类 DetailFragment 扩展了 FragmentActivity 并且在里面我有扩展片段的内部类,现在我该如何调用这个方法? 我还需要 DetailFragment 类中的上下文或这个,你能帮我解决这个问题吗【参考方案3】:您可以检查是否已有参数,如果有,只需添加/更新它们。
private static void initFrag(Fragment frag, Bundle args)
if (frag.getArguments() == null)
frag.setArguments(args);
else
//Consider explicitly clearing arguments here
frag.getArguments().putAll(args);
如果您不能安全地假设预先存在的参数仍然有效,您可能希望清除现有参数。
【讨论】:
【参考方案4】:这个全局变量:
private FragmentManager fragmentmanager;
private FragmentTransaction fragmenttransaction;
这些代码放在您的“List Fragment” onCreate() Activity 中:
fragmenttransaction = fragmentmanager.beginTransaction();
fragmenttransaction.replace(detailFragmentID, detailFragment, "test");
fragmenttransaction.addToBackStack(null);
fragmenttransaction.commit();
这些是 Drawerlistitem 点击事件:
@Override
public void onListItemClick(ListView l, View v, int position, long id)
Bundle bundle = new Bundle();
fragmenttransaction = fragmentmanager.beginTransaction();
if(fragmentmanager.findFragmentById("test") != null)
fragmenttransaction.remove(fragmentmanager.findFragmentByTag("test"));
Detailfragment detailFragment = (Detailfragment)getFragmentManager().findFragmentById(detailFragmentID);
bundle.putSerializable(BUNDLE_KEY, obj);// passing this object
detailFragment.setArguments(bundle);
fragmenttransaction.replace(detailFragmentID, detailFragment, "test");
fragmenttransaction.addToBackStack(null);
fragmenttransaction.commit();
现在按原样扩展片段代码:
Bundle b = getArguments();
b.getSerializable(BUNDLE_KEY);
【讨论】:
【参考方案5】:对话片段的公共方法
public void setBundle(final Bundle bundle)
final Bundle arguments = getArguments();
arguments.clear();
arguments.putAll(bundle);
显示或更新对话片段
public void showMessageDialogue(final String tag, final Bundle bundle)
final Fragment fragment = mFragmentManager.findFragmentByTag(tag);
if (fragment != null && fragment instanceof MessageDialogueFragment)
((MessageDialogueFragment) fragment).setBundle(bundle);
else
final MessageDialogueFragment messageDialogueFragment = new MessageDialogueFragment();
messageDialogueFragment.setArguments(bundle);
messageDialogueFragment.show(mFragmentManager, tag);
【讨论】:
以上是关于片段已激活 - 尝试 setArguments 时的主要内容,如果未能解决你的问题,请参考以下文章