您可以在 中获取自定义视图的测量值。onSizeChanged
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// use the provided width and height for whatever you need
}
解释
创建视图时,将按以下方法的调用顺序进行调用:
- 构造 函数
-
CustomView(Context context)
(如果以编程方式创建)
-
CustomView(Context context, AttributeSet attrs)
(如果从 xml 创建)
-
onFinishInflate
(假设您使用了 xml 构造函数)
onAttachedToWindow
onMeasure
onSizeChanged
onLayout
onDraw
最早可以获得视图的测量值是在 中。在此之前,宽度和高度是 .但是,您唯一应该做的就是确定视图的大小。此方法被调用多次,而视图告诉父级它想要多大,但父级正在确定实际的最终大小。(请参阅此答案,了解如何使用。onMeasure
0
onMeasure
onMeasure
如果要实际将测量的大小用于任何操作,最早可以这样做的地方是 。每当创建视图时都会调用它,因为大小从更改为任何大小。onSizeChanged
0
您也可以使用 ,尽管据我所知,它用于自定义自定义视图的任何子视图的布局方式。它也可能比 更频繁地被调用,例如,如果您在大小实际上没有变化时调用。onLayout
onLayout
onSizeChanged
requestLayout()
您还可以使用 和 访问 中的大小。但是,如果您使用它们进行任何繁重的计算,则最好事先执行此操作。一般来说,尽量避免使用,因为它可能会被多次调用。(每当被调用时,它就会被调用。onDraw
getMeasuredWidth()
getMeasuredHeight()
onDraw
invalidate()
亲眼看看
如果您不相信我,则可以在下面的自定义视图中看到事件的调用顺序。下面是输出:
XML constructor called, measured size: (0, 0)
onFinishInflate called, measured size: (0, 0)
onAttachedToWindow called, measured size: (0, 0)
onMeasure called, measured size: (350, 1859)
onMeasure called, measured size: (350, 350)
onMeasure called, measured size: (350, 2112)
onMeasure called, measured size: (350, 350)
onSizeChanged called, measured size: (350, 350)
onLayout called, measured size: (350, 350)
onDraw called, measured size: (350, 350)
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.viewlifecycle.CustomView
android:id="@+id/customView"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@color/colorAccent"/>
</RelativeLayout>
自定义视图.java
public class CustomView extends View {
private void printLogInfo(String methodName) {
Log.i("TAG", methodName + " called, measured size: (" + getMeasuredWidth() + ", " + getMeasuredHeight() + ")");
}
// constructors
public CustomView(Context context) {
super(context);
printLogInfo("Programmatic constructor");
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
printLogInfo("XML constructor");
}
// lifecycle methods
@Override
protected void onFinishInflate() {
super.onFinishInflate();
printLogInfo("onFinishInflate");
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
printLogInfo("onAttachedToWindow");
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
printLogInfo("onMeasure");
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
printLogInfo("onSizeChanged");
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
printLogInfo("onLayout");
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
printLogInfo("onDraw");
}
}
进一步阅读