http://www.binkery.com/archives/492.html
Fragment的創(chuàng)建
在Fragment的回調(diào)中 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是怎么賦值的呢,我們繼續(xù)追源碼
// 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;
我們進(jìn)入的源碼中看Fragment中的onCreateView方法是 performCreateView
調(diào)用了
View performCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (mChildFragmentManager != null) {
mChildFragmentManager.noteStateNotSaved();
}
return onCreateView(inflater, container, savedInstanceState);
}
但是在Fragment中 并沒有地方去調(diào)用 performCreateView
锰悼,跟fragment有關(guān)的 無非就是 FragmentManager
,所以我們?nèi)?FragmentManager
中找, 果然發(fā)現(xiàn) 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();
我們追進(jìn) 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;
}
繼續(xù)
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) , 繼續(xù)
Runnable mExecCommit = new Runnable() {
@Override
public void run() {
execPendingActions();
}
};
execPendingActions中有用的操作是 startPendingDeferredFragments(); 繼續(xù)追 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);
}
}
終于到關(guān)鍵方法了团赏,moveToState
是處理Fragment狀態(tài)的
繼續(xù)讀代碼我們可以看到
if (f.mHidden) f.mView.setVisibility(View.GONE);
f.onViewCreated(f.mView, f.mSavedFragmentState);
由此可看hide()的基本原理就是 將Fragment的 mView 不可見
小注 : 如果我們在hide(mFragmentB)之后 箕般,手動將 mFragmentB的view.setVisible(View.Visible); 的話,會導(dǎo)致hide失效 舔清。