android - 为什么我的 android 自定义 View 不是方形的?

标签 android android-custom-view measure

我创建了一个自定义 View 来显示我正在开发的游戏的游戏板。游戏板必须始终是正方形。所以 with 和 height 应该是一样的。我关注了this tutorial为达到这个。

我将以下代码添加到我的自定义 View 中:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    int width = getMeasuredWidth();
    int height = getMeasuredHeight();
    int widthWithoutPadding = width - getPaddingLeft() - getPaddingRight();
    int heigthWithoutPadding = height - getPaddingTop() - getPaddingBottom();

    int maxWidth = (int) (heigthWithoutPadding * RATIO);
    int maxHeight = (int) (widthWithoutPadding / RATIO);

    if (widthWithoutPadding > maxWidth) {
        width = maxWidth + getPaddingLeft() + getPaddingRight();
    } else {
        height = maxHeight + getPaddingTop() + getPaddingBottom();
    }

    setMeasuredDimension(width, height);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    Paint p = new Paint();
    p.setStyle(Paint.Style.STROKE);
    p.setStrokeWidth(3);
    canvas.drawRect(0, 0, getMeasuredWidth() - 1, getMeasuredHeight() - 1, p);
}

我的自定义 View 的布局如下所示:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <view
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        class="com.peerkesoftware.nanograms.controls.GameBoard"
        android:id="@+id/view"
        android:background="@android:color/holo_purple"/>

</RelativeLayout>

在 onDraw 方法中绘制的正方形始终是正方形。那很好用。

在布局中,我添加了自定义 View 并为 View 提供了背景色。当我以纵向模式在设备上显示它时,一切正常,背景颜色填满了我在 onDraw 方法中绘制的正方形。

当我将设备切换到横向模式时,正方形仍然是正方形,但背景颜色的区域比那个大。它具有相同的高度,但宽度更大。但我不知道为什么。 getMeasuredWidth() 和 getMeasuredHeight() 方法返回正确的值。怎么会比那个还要大呢?

最佳答案

由于某些原因,您的 View 在 RelativeLayout 中不起作用。对于横向测量最终有以下限制(在我的手机上):

宽度 = MeasureSpec:正好 404;高度 = MeasureSpec: AT_MOST 388

因为这个实际宽度最终与测量宽度不同(在我的手机上测量=388,实际=404)。这就是为什么您会看到背景超出了您的矩形。您可以通过向 onDraw 和 onMeasure 添加一些日志记录来自己检查。

此外,尊重测量模式也无济于事,测量仍然以与上述相同的结果结束。

解决方案是使用不同的布局。 LinearLayout 和 FrameLayout 为我工作。 此外,使用 getWidth() 和 getHeight() 在 onDraw 中使用实际 View 大小也是一个好主意。

如果你真的需要 RelativeLayout,你可以添加一个子 FrameLayout 来容纳你的 View ,如下所示:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
        <view
            android:id="@+id/view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            class="com.peerkesoftware.nanograms.controls.GameBoard"
            android:background="@android:color/holo_purple" />
    </FrameLayout>
</RelativeLayout>

关于android - 为什么我的 android 自定义 View 不是方形的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17228741/

相关文章:

java - Android:扩展CardView可以扩展哪些内容

c# - 将具有多个参数的函数作为参数传递

android - 是什么触发了 View 的 measure() 被调用

Android DialogFragment : How to preserve view in multiple show() invocation?

Android - 如何获得调用 Activity ?

Android:你如何拥有多个具有相同枚举的 attr?

android - 编译版本与最低要求版本 Android

curl - 如何使用 cURL 同时测量请求和响应时间?

android - Jetpack Compose - 居中文本

Android - 如何从小部件启动 Activity 并返回主屏幕