3

内部に円だけを含むカスタム ビューがあります。その寸法に問題があります。

と の両方を無効onSizeChanged()にしまし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 に答える