在FragmentActivity添加一个fragment
FragmentManager supportFragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
// fragmentTransaction.add(R.id.container,new ChatFragment());
fragmentTransaction.replace(R.id.container,new ChatFragment());
fragmentTransaction.commit();
一。FragmentActivity中,如何控制fragment的add和remove,以及和acitivity之间的关联?
fragmentActivity中初始化一个FragmentController实例,mFragments,mFragments中传入了一个hostCallback对象,hostCallback对象中带有FragmentActivity的对象和context等信息,并初始化了
FragmentManagerImpl的对象;
在FragmentActiviy中通过调用mFragments中的方法,mFragments中的方法再调用hostCallBack.mFragmentManagerImpl中对应的方法,来控制fragment的中的方法的执行,fragment中也会通过mFragmentManagerImpl获取到hostCallback对象,自然可以获取到FragmentActivity对象和context对象;
具体源码截取如下
// 创建FragmentController对象,传入HostCallbacks对象
inal FragmentController mFragments = FragmentController.createController(new HostCallbacks());
// HostCallbacks构造方法如下,是FragmentActivity的内部类
class HostCallbacks extends FragmentHostCallback<FragmentActivity> implements
ViewModelStoreOwner,
OnBackPressedDispatcherOwner {
public HostCallbacks() {
super(FragmentActivity.this /*fragmentActivity*/);
}
…
}
FragmentHostCallback的内部属性如下
public abstract class FragmentHostCallback<E> extends FragmentContainer {
@Nullable private final Activity mActivity; // 持有activity的对象
@NonNull private final Context mContext; // 持有Context的对象
@NonNull private final Handler mHandler;
private final int mWindowAnimations;
// 初始化FragmentManagerImpl的对象
final FragmentManagerImpl mFragmentManager = new FragmentManagerImpl();
public FragmentHostCallback(@NonNull Context context, @NonNull Handler handler,
int windowAnimations) {
this(context instanceof Activity ? (Activity) context : null, context, handler,
windowAnimations);
}
FragmentHostCallback(@NonNull FragmentActivity activity) {
this(activity, activity /*context*/, new Handler(), 0 /*windowAnimations*/);
}
FragmentHostCallback(@Nullable Activity activity, @NonNull Context context,
@NonNull Handler handler, int windowAnimations) {
mActivity = activity;
mContext = Preconditions.checkNotNull(context, "context == null");
mHandler = Preconditions.checkNotNull(handler, "handler == null");
mWindowAnimations = windowAnimations;
}
…
}
二。了解这些后,分析第一行代码:getSupportFragmentManager(),
/**
* Return the FragmentManager for interacting with fragments associated
* with this activity.
*/
@NonNull
public FragmentManager getSupportFragmentManager() {
return mFragments.getSupportFragmentManager();
}
FragmentController中,是获取的host中的mFragmentManager
/**
* Returns a {@link FragmentManager} for this controller.
*/
@NonNull
public FragmentManager getSupportFragmentManager() {
return mHost.mFragmentManager;
}
比如:FragmentActivity中onCreateView方法
@Override
@Nullable
public View onCreateView(@NonNull String name, @NonNull Context context,
@NonNull AttributeSet attrs) {
final View v = dispatchFragmentsOnCreateView(null, name, context, attrs);
if (v == null) {
return super.onCreateView(name, context, attrs);
}
return v;
}
@Nullable
final View dispatchFragmentsOnCreateView(@Nullable View parent, @NonNull String name,
@NonNull Context context, @NonNull AttributeSet attrs) {
return mFragments.onCreateView(parent, name, context, attrs);
}
FragmentController中
@Nullable
public View onCreateView(@Nullable View parent, @NonNull String name, @NonNull Context context,
@NonNull AttributeSet attrs) {
return mHost.mFragmentManager.onCreateView(parent, name, context, attrs);
}
mFragmentManager中的onCreateView,比较长,删减了
@Override
@Nullable
public View onCreateView(@Nullable View parent, @NonNull String name, @NonNull Context context,
@NonNull AttributeSet attrs) {
if (!"fragment".equals(name)) {
return null;
}
String fname = attrs.getAttributeValue(null, "class");
…
// If we haven't finished entering the CREATED state ourselves yet,
// push the inflated child fragment along. This will ensureInflatedFragmentView
// at the right phase of the lifecycle so that we will have mView populated
// for compliant fragments below.
if (mCurState < Fragment.CREATED && fragment.mFromLayout) {
// 重点,如果fragment没有创建,开始创建,
moveToState(fragment, Fragment.CREATED, 0, 0, false);
} else {
moveToState(fragment);
}
if (fragment.mView == null) {
throw new IllegalStateException("Fragment " + fname
+ " did not create a view.");
}
if (id != 0) {
fragment.mView.setId(id);
}
if (fragment.mView.getTag() == null) {
fragment.mView.setTag(tag);
}
return fragment.mView;
}
moveTostate方法比较多,删减
void moveToState(Fragment f, int newState, int transit, int transitionStyle,
boolean keepActive) {
。。。。
switch (f.mState) {
。。。
case Fragment.CREATED:
。。。
containe = (ViewGroup) mContainer.onFindViewById(f.mContainerId);
if (container == null && !f.mRestored) {
String resName;
try {
resName = f.getResources().getResourceName(f.mContainerId);
} catch (Resources.NotFoundException e) {
resName = "unknown";
}
throwException(new IllegalArgumentException(
"No view found for id 0x"
+ Integer.toHexString(f.mContainerId) + " ("
+ resName
+ ") for fragment " + f));
}
}
f.mContainer = container;
// 重点:执行fragment的createview方法
f.performCreateView(f.performGetLayoutInflater(
f.mSavedFragmentState), container, f.mSavedFragmentState);
。。。。
}
。。。。
}
Fragment中的performCreateView方法如下:
void performCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
mChildFragmentManager.noteStateNotSaved();
mPerformedCreateView = true;
mViewLifecycleOwner = new FragmentViewLifecycleOwner();
// 重点:执行了onCreateView方法
mView = onCreateView(inflater, container, savedInstanceState);
if (mView != null) {
// Initialize the view lifecycle
mViewLifecycleOwner.initialize();
// Then inform any Observers of the new LifecycleOwner
mViewLifecycleOwnerLiveData.setValue(mViewLifecycleOwner);
} else {
if (mViewLifecycleOwner.isInitialized()) {
throw new IllegalStateException("Called getViewLifecycleOwner() but "
+ "onCreateView() returned null");
}
mViewLifecycleOwner = null;
}
}
三。FragmentManager:
是个抽象类,其实现类为:FragmentManagerImpl,FragmentManagerImpl里面有final
ArrayList<Fragment> mAdded = new ArrayList<>();
final HashMap<String, Fragment> mActive = new HashMap<>();
mAdded列表是fragment被added,没有从activity中removed或者detached;
mActive列表是被added过的所有的fragment,只有以下两种情况fragment会被mActive列表中移除
1.它已经从activity中移除,并且不在backstack中。
2.一个事务从backstack弹出,并且在一个片段上的add或replace操作被detach/remove,该片段现在不再被backstack引用。
mAdded,mActive相关参考链接:https://stackoverflow.com/questions/25695960/difference-between-madded-mactive-in-source-code-of-support-fragmentmanager
1.fragmentManager,FragmentTransaction,backStackRecord三者联系
supportFragmentManager.beginTransaction();获取的是backStackRecord的实例;
@NonNull
@Override
public FragmentTransaction beginTransaction() {
return new BackStackRecord(this);
}
backStackRecord是fragmentTransaction的子类
final class BackStackRecord extends FragmentTransaction implements
FragmentManager.BackStackEntry, FragmentManagerImpl.OpGenerator
当我们调用add/或者replace方法时,是把信息组装到FragmentTrasaction的Op中,并附有操作标记,如OP_ADD等,处理Op是在backStackRecord的executeOps()方法中
/**
* Executes the operations contained within this transaction. The Fragment states will only
* be modified if optimizations are not allowed.
*/
void executeOps() {
final int numOps = mOps.size();
for (int opNum = 0; opNum < numOps; opNum++) {
final Op op = mOps.get(opNum);
final Fragment f = op.mFragment;
if (f != null) {
f.setNextTransition(mTransition, mTransitionStyle);
}
switch (op.mCmd) {
case OP_ADD:
f.setNextAnim(op.mEnterAnim);
mManager.addFragment(f, false);
break;
case OP_REMOVE:
f.setNextAnim(op.mExitAnim);
mManager.removeFragment(f);
break;
case OP_HIDE:
f.setNextAnim(op.mExitAnim);
mManager.hideFragment(f);
break;
case OP_SHOW:
f.setNextAnim(op.mEnterAnim);
mManager.showFragment(f);
break;
case OP_DETACH:
f.setNextAnim(op.mExitAnim);
mManager.detachFragment(f);
break;
case OP_ATTACH:
f.setNextAnim(op.mEnterAnim);
mManager.attachFragment(f);
break;
case OP_SET_PRIMARY_NAV:
mManager.setPrimaryNavigationFragment(f);
break;
case OP_UNSET_PRIMARY_NAV:
mManager.setPrimaryNavigationFragment(null);
break;
case OP_SET_MAX_LIFECYCLE:
mManager.setMaxLifecycle(f, op.mCurrentMaxState);
break;
default:
throw new IllegalArgumentException("Unknown cmd: " + op.mCmd);
}
if (!mReorderingAllowed && op.mCmd != OP_ADD && f != null) {
mManager.moveFragmentToExpectedState(f);
}
}
if (!mReorderingAllowed) {
// Added fragments are added at the end to comply with prior behavior.
mManager.moveToState(mManager.mCurState, true);
}
}
最终OP_ADD/OP_REMOVE等操作是在FragmentManagerImpl中实现具体的添加或者移除fragment的操作;具体可以看源码,不再附源码;
四。fragmentTransaction.replace/add(R.id.container,new ChatFragment());
传入的containerId,如果是0,fragment无法添加到一个容器上,无法展示,但是可以添加成功,可以做后台服务等操作;
网友评论