一.LayoutInflater
开发时,很多时候会用到LayoutInflater来加载指定的布局
LayoutInflater inflater = (LayoutInflater)context.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
// 或者通过from(Context context)获取实例
LayoutInflater inflater = LayoutInflater.from(context);
inflater.inflate(int resource, ViewGroup root);
在frameworks的SystemServiceRegistry.java中注册了此服务
registerService(Context.LAYOUT_INFLATER_SERVICE, LayoutInflater.class,
new CachedServiceFetcher<LayoutInflater>() {
@Override
public LayoutInflater createService(ContextImpl ctx) {
return new PhoneLayoutInflater(ctx.getOuterContext());
}});
new PhoneLayoutInflater,PhoneLayoutInflater继承了LayoutInflater
LayoutInflater是一个抽象类:
public abstract class LayoutInflater {
....
}
PhoneLayoutInflater:
public class PhoneLayoutInflater extends LayoutInflater {
private static final String[] sClassPrefixList = {
"android.widget.",
"android.webkit.",
"android.app."
};
/**
* Instead of instantiating directly, you should retrieve an instance
* through {@link Context#getSystemService}
*
* @param context The Context in which in which to find resources and other
* application-specific things.
*
* @see Context#getSystemService
*/
public PhoneLayoutInflater(Context context) {
super(context);
}
protected PhoneLayoutInflater(LayoutInflater original, Context newContext) {
super(original, newContext);
}
/** Override onCreateView to instantiate names that correspond to the
widgets known to the Widget factory. If we don't find a match,
call through to our super class.
*/
@Override protected View onCreateView(String name, AttributeSet attrs) throws ClassNotFoundException {
for (String prefix : sClassPrefixList) {
try {
View view = createView(name, prefix, attrs);
if (view != null) {
return view;
}
} catch (ClassNotFoundException e) {
// In this case we want to let the base class take a crack
// at it.
}
}
return super.onCreateView(name, attrs);
}
public LayoutInflater cloneInContext(Context newContext) {
return new PhoneLayoutInflater(this, newContext);
}
}
可以看到PhoneLayoutInflater实现了onCreateView()方法,当调用LayoutInflater的inflate()时,最终就会调用onCreateView(),从而创建出view
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {
......
final View temp = createViewFromTag(root, name, inflaterContext, attrs);
......
}
View createViewFromTag(View parent, String name, Context context, AttributeSet attrs,
boolean ignoreThemeAttr) {
......
try {
if (-1 == name.indexOf('.')) {
view = onCreateView(parent, name, attrs);
} else {
view = createView(name, null, attrs);
}
} finally {
mConstructorArgs[0] = lastContext;
}
......
}
protected View onCreateView(String name, AttributeSet attrs)
throws ClassNotFoundException {
return createView(name, "android.view.", attrs);
}
二.LayoutParams
LayoutParams继承于Android.View.ViewGroup.LayoutParams,是ViewGroup的一个内部抽象类,封装了Layout的位置、高、宽等信息
LayoutParams类是用于child view(子视图)向parent view(父视图)传达自己的意愿的一个东西
ViewGroup.LayoutParams类只能简单的设置高height以及宽width两个基本的属性,宽和高都可以设置成三种值:
1,FILL_PARENT,一个确定的值;
2,MATCH_PARENT;
3,WRAP_CONTENT。
ViewGroup.MarginLayoutParams类是ViewGroup.LayoutParams的子类,顾名思义,它只能设置child View的margin属性信息。
1、利用setMargins(left,top,right,bottom);
2、利用MarginLayoutParams对象params方法单独设置.topMargin
基本使用:
常用子类的简单使用:LinearLayout.LayoutParams、RelativeLayout.Params以及WindowManager.Params。
例子:
LayoutParams param = new LayoutParams(
0, LayoutParams.MATCH_PARENT);
//param.gravity = Gravity.CENTER_VERTICAL;
param.weight = 1;
view.setLayoutParams(param);
addView(view,i);