本文基于
compile 'com.android.support:percent:26+'
分析
在PercentFrameLayout
和PercentRelativeLayout
中都重写了
generateDefaultLayoutParams()
和generateLayoutParams()
方法。
PercentFrameLayout
的重写
public class PercentFrameLayout extends FrameLayout {
//省略其他代码
@Override
protected LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(getContext(), attrs);
}
}
PercentRelativeLayout
public class PercentRelativeLayout extends RelativeLayout {
//省略其他代码
@Override
protected LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(getContext(), attrs);
}
}
可以看到它们两者的实现是很相似的,那么generateDefaultLayoutParams()
和generateLayoutParams()
到底有何用?什么时候回调?
一下分析以PercentFrameLayout
为例,PercentRelativeLayout
类似。
generateDefaultLayoutParams
generateDefaultLayoutParams()
方法属于ViewGroup
,那么我们看一看ViewGroup
中对于generateDefaultLayoutParams()
方法的解析。
/** * Returns a set of default layout parameters. These parameters are requested * when the View passed to {@link #addView(View)} has no layout parameters * already set. If null is returned, an exception is thrown from addView. * * @return a set of default layout parameters or null */
protected LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}
generateDefaultLayoutParams()
在ViewGroup
中有两处调用到,这里展示其中一处:
/** * Adds a child view. If no layout parameters are already set on the child, the * default parameters for this ViewGroup are set on the child. * * <p><strong>Note:</strong> do not invoke this method from * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)}, * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p> * * @param child the child view to add * @param index the position at which to add the child * * @see #generateDefaultLayoutParams() */
public void addView(View child, int index) {
if (child == null) {
throw new IllegalArgumentException("Cannot add a null child view to a ViewGroup");
}
LayoutParams params = child.getLayoutParams();
if (params == null) {
params = generateDefaultLayoutParams();
if (params == null) {
throw new IllegalArgumentException("generateDefaultLayoutParams() cannot return null");
}
}
addView(child, index, params);
}
通过读上面的注释和代码,可以知道原来平常我们调用addView
的方法时,不指定LayoutParams
,是通过generateDefaultLayoutParams()
获取默认的LayoutParams
属性的。