【问题标题】:Android RelativeLayout align center of one view on top right corner of another viewAndroid RelativeLayout 将一个视图的中心对齐到另一个视图的右上角
【发布时间】:2012-05-11 03:16:23
【问题描述】:

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

我想尝试在 RelativeLayout 中创建类似以下图像的内容:

该框是它自己的视图,我想让包含橙色圆圈的视图居中于包含蓝色框的视图的右上角。

我尝试使用 android:alignTop="boxView"android:alignRight="boxView" 但这将我的橙色圆圈完全放在我的盒子里。我希望它使圆圈居中于框的右上角。

有人知道我如何使用 RelativeLayout 获得该结果吗?最好不必为橙色点视图硬编码远离屏幕边缘的边距。

【问题讨论】:

  • 您为什么不想为此使用边距。保证金似乎是实现这一目标的完美方式。
  • 我只是不想给它离屏幕边缘多远的边距。如果我可以将它与盒子对齐,然后将其上下移动其直径的一半,并留出实际理想的边距。但我只能通过告诉它离屏幕边缘有多远而不是离我想要对齐的点有多远来弄清楚如何做到这一点。

标签: android alignment android-relativelayout


【解决方案1】:

使用约束布局很容易实现。

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

<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"/>

【讨论】:

    【解决方案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>
    

    【讨论】:

      【解决方案3】:

      您可以使用 ConstraintLayout 圆形定位,只需将视图对齐 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>
      

      【讨论】:

        【解决方案4】:

        此代码创建您要查找的内容,但确实使用了边距。如果这是您正在创建的动态结构,现在您可以在代码中设置边距。如您所见,我使用负边距将右上角的形状移出蓝色框。这些需要是您尝试移动的圆圈高度的一半。您可以在代码中完成所有这些操作,以使右上角的圆居中。

            <?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。一种解决方法是选择一个绝对大于图像的尺寸,并在具有该确定尺寸的视图周围添加一个包装布局(原始视图居中),然后您可以计算一半。
        • 负边距不受官方支持,在某些设备上无法正常工作。 issuetracker.google.com/issues/37103660