gpt4 book ai didi

java - 何时调用 View.onMeasure()?

转载 作者:IT老高 更新时间:2023-10-28 20:34:28 25 4
gpt4 key购买 nike

什么时候

View.onMeasure(int widthMeasureSpec, int heightMeasureSpec)

打电话了?我有一个 Activity需要在 onMeasure 之后执行的操作已被调用。

我的问题与 the unanswered question posted here 相同. View文档指出 onMeasurerequestLayout() 时调用被调用,当它认为它不再适合其当前边界时,它显然是由对自身的 View 调用的。

但是,这并不能告诉我我的 Activity 何时可以假定我的 View已被测量。我用过this code延长 ImageView形成 TouchImageView。 It was suggested here我应该使用 onMeasure缩放我的图像的方法。我希望更新 TextView 的值在 ImageView 之后已被测量以显示图像已缩放的百分比。

最佳答案

您可以在 onSizeChanged 中获取自定义 View 的测量值。

@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
}

说明

创建 View 时,调用以下方法的顺序如下:

  1. 构造函数
    • CustomView(Context context)(如果以编程方式创建)
    • CustomView(Context context, AttributeSet attrs)(如果从 xml 创建)
  2. onFinishInflate(假设您使用了 xml 构造函数)
  3. onAttachedToWindow
  4. onMeasure
  5. onSizeChanged
  6. onLayout
  7. onDraw

您最早可以在 onMeasure 中获得 View 的测量值。在此之前,宽度和高度是 0。但是,您应该在 onMeasure 中做的唯一事情是确定 View 的大小。当 View 告诉父级它想要多大但父级正在确定实际的最终大小时,此方法会被调用多次。 (请参阅 this answer 了解如何使用 onMeasure。)

如果您想实际使用测量的大小,最早可以在 onSizeChanged 中执行此操作。每当创建 View 时都会调用它,因为大小从 0 变为任何大小。

您也可以使用 onLayout,但据我了解,onLayout 用于自定义自定义 View 的任何 subview 的布局方式。它也可能比 onSizeChanged 更频繁地被调用,例如,如果在大小实际上没有改变时调用 requestLayout()

您还可以使用 getMeasuredWidth()getMeasuredHeight()onDraw 中访问尺寸。但是,如果您使用它们进行任何繁重的计算,最好事先进行。一般来说,尽量避免使用 onDraw,因为它可能会被多次调用。 (只要 invalidate() 被调用,它就会被调用。)

自己看看

如果您不相信我,您可以在下面的自定义 View 中查看事件的顺序。这是输出:

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>

CustomView.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");
}
}

进一步阅读

关于java - 何时调用 View.onMeasure()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6631105/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com