美文网首页
FragmentManager.show(fragment)

FragmentManager.show(fragment)

作者: 弘法大师 | 来源:发表于2017-05-24 18:55 被阅读0次

    http://www.binkery.com/archives/492.html

    Fragment的创建

    在Fragment的回调中 onCreateView 我们会初始化一个view 并 reture.
    如下,我们reture的 myView 会被保存到Fragment中

        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            View  myView = new MineView(getActivity());
            return myView;
        }
    

    来看fragment的成员变量,那么可以猜想mView就是 onCreateView 所返回的,那么这个mView是怎么赋值的呢,我们继续追源码

        // The parent container of the fragment after dynamically added to UI.
        ViewGroup mContainer;
        
        // The View generated for this fragment.
        View mView;
        
        // The real inner view that will save/restore state.
        View mInnerView;
    

    我们进入的源码中看Fragment中的onCreateView方法是 performCreateView调用了

    View performCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            if (mChildFragmentManager != null) {
                mChildFragmentManager.noteStateNotSaved();
            }
            return onCreateView(inflater, container, savedInstanceState);
        }
    

    但是在Fragment中 并没有地方去调用 performCreateView ,跟fragment有关的 无非就是 FragmentManager ,所以我们去 FragmentManager中找, 果然发现 mView 就是我们猜想的那样

    f.mContainer = container;
                                f.mView = f.performCreateView(f.getLayoutInflater(
                                        f.mSavedFragmentState), container, f.mSavedFragmentState);
    

    Fragment的隐藏和显示

    通常我们显示或隐藏Fragment 是通过如下的方式

     ((FragmentActivity) getContext()).getSupportFragmentManager().beginTransaction().show(mFragmentAt).commitAllowingStateLoss();
     ((FragmentActivity) getContext()).getSupportFragmentManager().beginTransaction().hide(mFragmentB).commitAllowingStateLoss();
    

    我们追进 commitAllowingStateLoss 看做了什么

        public int commitAllowingStateLoss() {
            return commitInternal(true);
        }
        
        int commitInternal(boolean allowStateLoss) {
            if (mCommitted) throw new IllegalStateException("commit already called");
            if (FragmentManagerImpl.DEBUG) {
                Log.v(TAG, "Commit: " + this);
                LogWriter logw = new LogWriter(TAG);
                PrintWriter pw = new PrintWriter(logw);
                dump("  ", null, pw, null);
            }
            mCommitted = true;
            if (mAddToBackStack) {
                mIndex = mManager.allocBackStackIndex(this);
            } else {
                mIndex = -1;
            }
            mManager.enqueueAction(this, allowStateLoss);
            return mIndex;
        }
    

    继续

       public void enqueueAction(Runnable action, boolean allowStateLoss) {
            if (!allowStateLoss) {
                checkStateLoss();
            }
            synchronized (this) {
                if (mDestroyed || mHost == null) {
                    throw new IllegalStateException("Activity has been destroyed");
                }
                if (mPendingActions == null) {
                    mPendingActions = new ArrayList<Runnable>();
                }
                mPendingActions.add(action);
                if (mPendingActions.size() == 1) {
                    mHost.getHandler().removeCallbacks(mExecCommit);
                    mHost.getHandler().post(mExecCommit);
                }
            }
        }
    

    有用的操作就是 post(mExecCommit) , 继续

    Runnable mExecCommit = new Runnable() {
            @Override
            public void run() {
                execPendingActions();
            }
        };
    
    

    execPendingActions中有用的操作是 startPendingDeferredFragments(); 继续追 performPendingDeferredStart

        public void performPendingDeferredStart(Fragment f) {
            if (f.mDeferStart) {
                if (mExecutingActions) {
                    // Wait until we're done executing our pending transactions
                    mHavePendingDeferredStart = true;
                    return;
                }
                f.mDeferStart = false;
                moveToState(f, mCurState, 0, 0, false);
            }
        }
    

    终于到关键方法了,moveToState是处理Fragment状态的

    继续读代码我们可以看到

    if (f.mHidden) f.mView.setVisibility(View.GONE);
    f.onViewCreated(f.mView, f.mSavedFragmentState);
    

    由此可看hide()的基本原理就是 将Fragment的 mView 不可见

    小注 : 如果我们在hide(mFragmentB)之后 ,手动将 mFragmentB的view.setVisible(View.Visible); 的话,会导致hide失效 。

    相关文章

      网友评论

          本文标题:FragmentManager.show(fragment)

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