美文网首页
android DialogFragment 的show()的问

android DialogFragment 的show()的问

作者: 木木禾木 | 来源:发表于2020-04-24 16:47 被阅读0次

    在使用DialogFragment的show时,会发生一些异常,整理一下。

    1、重复添加的异常

    java.lang.IllegalStateException: Fragment already added

    2、状态相关的异常

    java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState


    带着问题来看看DialogFragment源码中的show做了什么:

        /**
         * Display the dialog, adding the fragment to the given FragmentManager.  This
         * is a convenience for explicitly creating a transaction, adding the
         * fragment to it with the given tag, and committing it.  This does
         * <em>not</em> add the transaction to the back stack.  When the fragment
         * is dismissed, a new transaction will be executed to remove it from
         * the activity.
         * @param manager The FragmentManager this fragment will be added to.
         * @param tag The tag for this fragment, as per
         * {@link FragmentTransaction#add(Fragment, String) FragmentTransaction.add}.
         */
        public void show(FragmentManager manager, String tag) {
            mDismissed = false;
            mShownByMe = true;
            FragmentTransaction ft = manager.beginTransaction();
            ft.add(this, tag);
            ft.commit();
        }
    

    源码中的show方法很简单,所以原因也很明显:

    1. 由于直接使用 FragmentTransaction 的 add() 方法,所以会出现重复添加;
    2. 由于使用的是 FragmentTransaction 的 commit() ,而不是 commitAllowingStateLoss() ,所以会出现状态问题的异常。(之前记得有分析过commit与commitAllowingStateLoss的区别 android Fragment的commit与commitAllowingStateLoss

    问题修复

    重写DialogFragment的show(),如下:

        @Override
        public void show(FragmentManager manager, String tag) {
            //避免重复添加的异常 java.lang.IllegalStateException: Fragment already added
            Fragment fragment = manager.findFragmentByTag(tag);
            if (fragment != null) {
                FragmentTransaction fragmentTransaction = manager.beginTransaction();
                fragmentTransaction.remove(fragment);
                fragmentTransaction.commitAllowingStateLoss();
            }
            //避免状态丢失的异常 java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
            try {
                super.show(manager, tag);
            } catch (IllegalStateException e) {
                e.printStackTrace();
            }
        }
    

    当然也可以通过反射来调用 commitAllowingStateLoss(),只是复杂度比较高,不是很必要。

    关闭DialogFragment也要尽量使用dismissAllowingStateLoss() 而不是 dismiss() 额~


    相关文章

      网友评论

          本文标题:android DialogFragment 的show()的问

          本文链接:https://www.haomeiwen.com/subject/yabfwhtx.html