上篇文章我们讲了Fragment的生命周期管理,对Fragment整个运行机制都会比较清楚了,这节我们分析Fragment的View管理。
一,Fragment的两种定义方式
1,在layout xml里通过fragment标签定义,这种方式定义的fragment是由LayoutInflater在解析xml文件的时候创建。在Activity的onCreate方法里,会通过setContentView方法设置layout id,继而调用LayoutInflater的inflate方法解析xml。LayoutInflater在解析xml的时候,就会实例化出Fragment。
2,Fragment还可以通过代码动态的new Fragment实例,通过FragmentTransaction的add/replace方法随时添加,上篇文章已经介绍过FragmentManager的addFragment流程。
二,Fragment的fragmentId、containerId、tag的意义
fragmentId和tag都是用来标识fragment自身的,containerId是fragment的View的父控件的id,是View的容器。静态和动态两种Fragment的containerId、fragmentId、tag的生成方式也是不一样的。
1,代码动态创建的Fragment
FragmentTransaction的add和replace都有containerViewId和tag参数,containerViewId就是fragment的containerId,并且fragmentId也同时会设置成和containerId一样。从这点也可以看出如果往同一个ViewGroup里add两个不同的Fragment,那么他们的fragmentId是一样的。fragmentId一样的话,会影响FragmentManager的findFragmentById的结果,这个方法只会返回第一个fragmentId等于目标id的Fragment。tag和fragmentId一样,都是用来标识Fragment自身,如果两个fragment的tag相同,则会影响findFragmentByTag的结果。
2,Layout xml里定义的Fragment
Layout xml方式的fragment的实例化流程是: Activity.onCreate -> Activity.setContentView -> PhoneWindow.setContentView -> LayouInflater.inflate->LayoutInflater.createViewFromTag -> Activity.onCreateView -> FragmentManager.onCreateView,因此在Activity的onCreate的时候会开始Fragment的创建。我们看看FragmentManager的onCreateView方法:
@Override
public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
String fname = attrs.getAttributeValue(null, "class");
TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.Fragment);
if (fname == null) {
fname = a.getString(com.android.internal.R.styleable.Fragment_name);
}
int id = a.getResourceId(com.android.internal.R.styleable.Fragment_id, View.NO_ID);
String