Java 何时调用View.onMeasure()?
什么时候 打电话?我有一个需要在调用后执行操作的Java 何时调用View.onMeasure()?,java,android,android-activity,view,onmeasure,Java,Android,Android Activity,View,Onmeasure,什么时候 打电话?我有一个需要在调用后执行操作的 我的问题和你的一样。文档说明了在调用时调用,当视图认为is不再适合其当前范围时,显然是由其自身的视图调用的 然而,这并没有告诉我什么时候我的活动可以假定我的活动已经被测量过。我曾经扩展到形成TouchImageView。我应该用这个方法来缩放我的图像。我希望在测量后更新a的值,以便显示图像缩放的百分比。当父视图需要计算布局时,调用onMeasure。通常,根据存在的不同子级及其布局参数,可以多次调用onMeasure 调用时最好的方法是(我认为)
我的问题和你的一样。文档说明了在调用时调用,当视图认为is不再适合其当前范围时,显然是由其自身的视图调用的
然而,这并没有告诉我什么时候我的活动可以假定我的活动已经被测量过。我曾经扩展到形成TouchImageView。我应该用这个方法来缩放我的图像。我希望在测量后更新a的值,以便显示图像缩放的百分比。当父视图需要计算布局时,调用onMeasure。通常,根据存在的不同子级及其布局参数,可以多次调用onMeasure 调用时最好的方法是(我认为)创建您自己的控件,扩展和覆盖onMeasure(只需调用super.onMeasure并执行您想执行的任何其他操作)
如果这样做,请记住,on Measure可能会使用不同的参数调用多次,因此所测量的内容可能不是实际显示内容的最终宽度和高度。您可以在
onSizeChanged
中获取自定义视图的测量值
View.onMeasure(int widthMeasureSpec, int heightMeasureSpec)
解释
创建视图时,以下方法的调用顺序如下:
(如果以编程方式创建)自定义视图(上下文)
(如果是从xml创建的)CustomView(上下文上下文,属性集属性)
onFinishInflate
(假设您使用了xml构造函数)onAttachedToWindow
onMeasure
onSizeChanged
onLayout
onDraw
onMeasure
中获取视图的测量值。在此之前,宽度和高度为0
。但是,在测量中,您应该做的唯一一件事就是确定视图的大小。当视图告诉父对象它希望有多大,但父对象正在确定实际的最终大小时,会多次调用此方法。(有关如何使用测量的信息,请参阅。)
如果您想实际使用测量的大小进行任何操作,最早的位置是onSizeChanged
。每当创建视图时都会调用它,因为大小从0
更改为任何大小
您也可以使用onLayout
,但据我所知,onLayout
用于自定义自定义视图的任何子视图的布局方式。例如,如果在大小没有实际更改的情况下调用requestLayout()
,则调用它的频率可能比调用大小更改的onSizeChanged
更高
您还可以使用getMeasuredWidth()
和getMeasuredHeight()
访问onDraw
中的大小。但是,如果您要使用它们进行任何繁重的计算,最好事先进行。一般来说,尽量避免使用onDraw
,因为它可能会被多次调用。(每当调用invalidate()
时,就会调用它。)
你自己看看吧
如果您不相信我的话,您可以在下面的自定义视图中看到事件的顺序。以下是输出:
@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
}
activity_main.xml
进一步阅读
onCreate
吗?@dankal444,不,自定义视图没有onCreate
方法。不过,构造函数是用于创建新视图对象的方法。在上面的CustomView.java示例中,有两种构造函数方法:CustomView(上下文)
和CustomView(上下文,属性集属性)
。
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)
<?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>
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");
}
}