Android相对布局:将一个视图的中心与另一个视图的右上角对齐

32

我有RelativeLayout的经验,但是我从来没有遇到过解决我面临的问题的方法(除了硬编码边距值,我想避免这种方式。)

我想尝试在RelativeLayout中创建像下面这张图片一样的东西:

enter image description here

盒子是它自己的View,我希望获得包含橙色圆圈的View位于包含蓝色盒子的View的右上角。

我尝试使用 android:alignTop="boxView"android:alignRight="boxView",但是那会把我的橙色圆圈完全放在我的盒子里。我希望它位于盒子右上角的正上方居中。

有人知道我如何在RelativeLayout中实现这个结果吗?最好不要硬编码远离屏幕边缘的橙点视图的边距。


为什么你不想使用margin来完成这个任务?Margin看起来是实现这个目标的完美方式。 - Bobbake4
我只是不想给它一个距离屏幕边缘有多远的边距。如果我能将其与框对齐,然后通过半径的一半向上和向上移动,并带有边距,那实际上就是理想的。但是我只能通过告诉它离屏幕边缘有多远来解决它,而不是离我想要对齐的点有多远。 - FoamyGuy
4个回答

32

这段代码可以创建你所需的效果,但使用了边距。如果你正在创建一个动态结构,现在可以在代码中设置边距。如你所见,我使用负边距将右上角的形状移出了蓝色框。这些边距需要是你要移动的圆形的一半高度。你可以在代码中完成所有这些工作,以使圆形居中于右上角。

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <LinearLayout
            android:id="@+id/linearLayout1"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true"
            android:background="#0000FF"
            android:orientation="vertical" >
        </LinearLayout>

        <LinearLayout
            android:layout_width="26dp"
            android:layout_height="26dp"
            android:layout_alignRight="@+id/linearLayout1"
            android:layout_alignTop="@+id/linearLayout1"
            android:layout_marginRight="-13dp"
            android:layout_marginTop="-13dp"
            android:background="#FF00FF"
            android:orientation="vertical" >
        </LinearLayout>

    </RelativeLayout>

请注意,如果第二个视图由图像调整大小,则此方法实际上无法正常工作,因为可绘制对象在DP中没有一致的大小(它们在像素中的大小从一个DPI桶跳到另一个而不是连续缩放)。因此,您不能只是做26dp / 2 = 13dp。一种解决方法是选择一个明显大于图像的大小,并在具有该确定大小的视图周围添加包装器布局(原始视图居中其中),然后您可以计算其一半。 - Karu
负边距不被官方支持,并且在某些设备上无法正常工作。 - Shroud

2

最佳和正确的做法:

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="@dimen/_10sdp">

    <View
        android:id="@+id/viewBox"
        android:layout_width="35dp"
        android:layout_height="35dp"
        android:background="@color/black"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent" />

    <View
        android:layout_width="15dp"
        android:layout_height="15dp"
        android:src="@drawable/ic_close"
        app:layout_constraintBottom_toTopOf="@+id/viewBox"
        app:layout_constraintLeft_toRightOf="@+id/viewBox"
        app:layout_constraintRight_toRightOf="@+id/viewBox"
        app:layout_constraintTop_toTopOf="@+id/viewBox" />

</androidx.constraintlayout.widget.ConstraintLayout>

1

使用约束布局非常容易实现这一点。

只需将圆的开始和结束约束设置为同一点,将顶部和底部约束设置为同一点(例如文本视图的右上角),如下所示:

<TextView
    android:id="@+id/newWarningLabel"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="left|center"
    android:lines="2"
    android:text="testtest"
    android:textColor="@color/white"
    android:textSize="12sp"
    android:textStyle="bold"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"/>

<TextView
    android:id="@+id/alertCounter"
    android:layout_width="20dp"
    app:layout_constraintStart_toStartOf="@id/newWarningLabel"
    app:layout_constraintEnd_toStartOf="@id/newWarningLabel"
    app:layout_constraintTop_toTopOf="@id/newWarningLabel"
    app:layout_constraintBottom_toTopOf="@id/newWarningLabel"
    android:layout_height="20dp"
    android:gravity="center"
    android:textColor="@color/white"
    android:textStyle="bold"
    android:textSize="10sp"
    android:visibility="visible"
    android:text="1"
    android:background="@drawable/red_circle"/>

enter image description here


1
您可以使用约束布局的环形定位,只需将视图对齐于45度角并调整半径即可:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:background="@color/colorAccent"
        android:id="@+id/view"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <LinearLayout
        android:background="@color/colorPrimary"
        android:id="@+id/alignedView"
        android:layout_width="30dp"
        android:layout_height="30dp"
        app:layout_constraintCircle="@id/view"
        app:layout_constraintCircleAngle="45"
        app:layout_constraintCircleRadius="60dp" />

</androidx.constraintlayout.widget.ConstraintLayout>

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