Fragment
Fragment源码分析!
FragmentActivity
- BaseFragmentActivityDonut:抽象类,直接继承Activity,它的主要作用是定义了抽象方法:
abstract View dispatchFragmentsOnCreateView(View parent, String name, Context context, AttributeSet attrs);
- BaseFragmentActivityHoneycomb:它主要是重写了BaseFragmentActivityDonut的
onCreateView
方法,针对SDN_INT>=11
做不同的处理。 - ActionBarActivity:已废弃
- AppCompatActivity 这两个及时功能上一样的,AppCompatActivity其实是在FragmentActivity上增加了ActionBar而已。
几个核心类
- FragmentActivity:它主要是负责与Activity生命周期事件的分发。
- FragmentController:上面的分发会传递给这个类,而它也不是实际的操作者,简单来说,它是负责继续将生命周期的操作分发给它持有的FragmentHostCallback中的FragmentManager。
- FragmentHostCallback:它持有FragmentActivity的Activity、Context、Handler等引用,为它所持有的FragmentManager提供资源。
- HostCallbacks:是FragmentActivity的内部类,继承FragmentHostCallback。
- FragmentManager:只是个抽象类
- FragmentManagerImpl FragmentManagerImpl是FragmentManager的具体实现类。它可以说是Fragment生命周期管理最重要的类
从使用分析
如何将fragment添加进来?
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(android.R.id.primary, new MyFragment());
ft.commitAllowingStateLoss();
1、getSupportFragmentManager
这里是为了获得FragmentManager对象。 最终是FragmentManagerImpl类返回的。
mFragments.getSupportFragmentManager()
FragmentActivity里的这个mFragments
成员变量是如此定义的:
final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
而内部类HostCallbacks
是这样的:
class HostCallbacks extends FragmentHostCallback<FragmentActivity>
这样,就把它持有FragmentActivity的Activity、Context、Handler等引用注入到了FragmentController里,即成员变量mHost
。
2、beginTransaction
public FragmentTransaction beginTransaction() {
return new BackStackRecord(this);
}
BackStackRecord
就是负责fragment的添加,删除,隐藏,显示等。
它维护了一个双向链表OP
:记录了命令类型,以及执行命令时的动画(分为push和pop动画),以及涉及到的相关的Fragment(比如replace方法,就涉及两个Fragment)
static final class Op {
Op next;
Op prev;
int cmd;
Fragment fragment;
int enterAnim;
int exitAnim;
int popEnterAnim;
int popExitAnim;
ArrayList<Fragment> removed;
}
3、replace or add
fragment的添加或替换只是BackStackRecord的双向链表的操作,最终都是会走到addOP()
方法上。
void addOp(Op op) {
if (mHead == null) {
mHead = mTail = op;
} else {
op.prev = mTail;
mTail.next = op;
mTail = op;
}
op.enterAnim = mEnterAnim;
op.exitAnim = mExitAnim;
op.popEnterAnim = mPopEnterAnim;
op.popExitAnim = mPopExitAnim;
mNumOp++;
}
4、commit or commitAllowingStateLoss
在run
里针对不同的指令完成不同的FragmentManager方法的调用:
static final int OP_NULL = 0;
static final int OP_ADD = 1;
static final int OP_REPLACE = 2;
static final int OP_REMOVE = 3;
static final int OP_HIDE = 4;
static final int OP_SHOW = 5;
static final int OP_DETACH = 6;
static final int OP_ATTACH = 7;
在moveToState
里发起fragment状态的修改,fragment的状态分为如下:
static final int INITIALIZING = 0; // Not yet created.
static final int CREATED = 1; // Created.
static final int ACTIVITY_CREATED = 2; // The activity has finished its creation.
static final int STOPPED = 3; // Fully created, not started.
static final int STARTED = 4; // Created and started, not resumed.
static final int RESUMED = 5; // Created started and resumed.
最低值是INITIALIZING状态,代表fragment刚创建,还未被add, 最高状态值是RESUMED,代表fragment处于前台。 所以moveToState内部分两条线,状态跃升,和状态降低,里面各有一个switch判断,注意到switch里每个case都没有break,这意味着,状态可以持续变迁,比如从INITIALIZING,一直跃升到RESUMED,将每个case都走一遍,每次case语句内,都会改变state的值。
Fragment栈的问题
public void onBackPressed() {
if (!mFragments.getSupportFragmentManager().popBackStackImmediate()) {
supportFinishAfterTransition();
}
}