为什么我的自定义View中的onMeasure()会被调用两次?

11

以下是我自定义 View 的代码:

XML 布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res/com.project.summary"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" 
    android:background="@color/BgColor">

    <com.project.summary.customview.CustomView
        android:id="@+id/customView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:colorValue="@color/textRed"
        app:textString="This the Custom View!!!"
        app:textSize="20sp"
        />

</LinearLayout>

我在CustomView.java文件中的代码:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    Log.e("140117", "onMeasure()"+this.getHeight()+"||"+this.getWidth());
}

测试活动的代码:

    public class CustomViewActivity extends Activity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.customview_layout);
    }
}

logcat 输出:

01-17 13:47:01.203: E/140117(11467): onMeasure()0||0
01-17 13:47:01.243: E/140117(11467): onMeasure()28||212
我在 StackOverflow 上搜索了,但没有人给出清晰的答案。能有人帮忙吗?

1
这是一件很正常的事情。如果你在一个RelativeLayout中,几乎肯定会被测量两次或更多次。 - Kevin Coppock
@kcoppock:感谢您的回复,您能告诉我为什么它会被调用两次吗?触发器是什么?当设置我的自定义视图权重属性时,onMeasure()被调用了四次!为什么? - linguowu
请查看此答案:https://dev59.com/E2855IYBdhLWcg3w7pGg#4069077 - Kevin Coppock
@kcoppock:再次感谢,答案只是说:“当您嵌套使用多个使用权重参数的LinearLayout时,布局传递可能特别昂贵,这需要对子项进行两次测量。”但是它没有解释何时使用权重参数会要求对子项进行两次测量? - linguowu
3个回答

12

一个父视图可能会多次调用其子视图的measure()方法。例如,父视图可能会在没有指定尺寸的情况下先测量每个子视图以了解它们想要的大小,然后如果所有子视图的未受限制的尺寸之和太大或太小(也就是说,如果子视图彼此之间不能达成一致,父视图将在第二次遍历时介入并设置规则),则再次使用实际数字调用measure()方法。 根据https://developer.android.com/guide/topics/ui/how-android-draws.html描述。


0
过去当我遇到类似的问题时,通常是因为我的“onAnAction”代码应该在活动的类代码内部,也就是在活动的onCreate方法中,而不是在自定义视图的类中。
这可能有效,但并不保证,通常需要一些调试和对Android生命周期的理解。

0

你的问题有遗漏吗?因为如果你重写了 onMeasure 方法,你必须调用 setMeasuredDimension(int, int),否则会出现 IllegalStateException 异常。在你的问题中似乎没有出现任何异常。


这应该是一个注释。 - user9599745

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接