3

我有一个自定义视图,里面只有一个圆圈。我的尺寸有问题。

我都覆盖了onSizeChanged()and onMeasure(),但我担心我错过了onMeasure(). 这个视图基本上只是一个圆,我覆盖了getSuggestedMinimumHeight()getSuggestedMinimumWidth()为了让它们都返回圆的半径。现在一切似乎都很好,直到我决定更新活动的其他一些组件。

当我在视图所在的活动中更新 a TextView(或 a )的文本时,我的视图会变小(在每次更新时)同时调用和。ButtononMeasure()onSizeChanged()

这是我的onMeasure()方法。我的问题是:为什么它的行为总是不一样?

@Override
protected int getSuggestedMinimumHeight() {
    return (int) (mCircleRadius + mCircleStrokeWidth/2);
}

@Override
protected int getSuggestedMinimumWidth() {
    return (int) (mCircleRadius + mCircleStrokeWidth/2);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.d("SIZES", "called onMeasure()");

    int minw = getPaddingLeft() + getPaddingRight() + getSuggestedMinimumWidth();

    int minh = getSuggestedMinimumHeight() + getPaddingBottom() + getPaddingTop();

    setMeasuredDimension(minw, minh);
}

这是布局的 XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res/com.nhasu"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <com.nhasu.ProgressCircleTimer
        android:id="@+id/progcircle_smallBreaks"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:padding="10dp"
        custom:circle_radius="300dp" />

    <Button
        android:id="@+id/btn" 
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_centerInParent="true"

        android:onClick="onStartClicked"
        android:text="@string/btn_start"
        android:textSize="40sp" />
</RelativeLayout>

请注意,我Button使用简单的Button.setText().

4

1 回答 1

3

您不需要onSizeChanged确定自定义视图的大小。调用时onSizeChanged,您的自定义视图已被测量和布局。

只需onMeasure适当地实施:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    Log.d("SIZES", "called onMeasure()");

    int minw = getPaddingLeft() + getPaddingRight() + getSuggestedMinimumWidth();
    int minh = getSuggestedMinimumHeight() + getPaddingBottom() + getPaddingTop();

    setMeasuredDimension(
            resolveSize(minw, widthMeasureSpec),
            resolveSize(minh, heightMeasureSpec));
}

public static int resolveSize(int childSize, int measureSpec) {
    int specMode = MeasureSpec.getMode(measureSpec);
    int specSize = MeasureSpec.getSize(measureSpec);
    switch (specMode) {
    case MeasureSpec.UNSPECIFIED:
        // Just return the child's size.
        return childSize;

    case MeasureSpec.AT_MOST:
        // Return the smallest of childSize and specSize
        return (specSize < childSize)? specSize : childSize;

    case MeasureSpec.EXACTLY:
        // Should honor parent-View's request for the given size.
        // If not desired, don't set the child's layout_width/layout_height to a fixed
        // value (nor fill_parent in certain cases).
        return specSize;
    }

    return childSize;
}

我在这个答案中添加了实现,resolveSize这样你就可以看到会发生什么,但它已经在View.resolveSize.

于 2013-02-26T18:45:46.653 回答