【问题标题】:Fragment already active - When trying to setArguments片段已激活 - 尝试 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);

现在在选定的项目上显示“片段已激活”。

这里有什么问题?我做错了什么?

【问题讨论】:

    标签: android android-fragments fragment android-listfragment


    【解决方案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);
                 } 
           }
        

        【讨论】:

          猜你喜欢
          • 2012-05-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-07-13
          • 2019-12-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多