如何将三个大小相同的视图与它们之间的较小视图重叠?

How do I overlap three equally-sized views with smaller views between them?

我正在尝试使三个按钮等间距并垂直对齐,并且它们之间的圆圈重叠,如下所示:

我 运行 遇到了困难,因为需要一个 LinearLayout 来平均分配三个按钮的权重,但是重叠视图最容易在 RelativeLayout 和 FrameLayout 中完成(我需要支持 <21 SDK,所以我不能将 z-index 与 LinearLayout 结合使用)。

当我将 "OR" 圆圈放在 Frame/RelativeLayouts 中时,没有简单的方法将它们设置为视图高度的 1/3,以便它们落在按钮之间。

如何将带有 OR 圆的 FrameLayout 分成三份以正确放置圆?

我找不到直接的解决方案,所以我要回答我自己的问题!如果您有更好的解决方案,请告诉我。

我想出的解决方案是将 LinearLayout 中的按钮布局在 FrameLayout 中,并适当地赋予它们权重。 OR 圆圈放在按钮之后的 FrameLayout 中,这样它们就会被绘制在顶部。但是,它们没有定位在 xml.

onCreate() 中,我用按钮测量了 LinearLayout 的绘制尺寸,然后将 OR 圆移动了三分之一加上圆的半径。

这里是相关的XML。重点是:

  • FrameLayout 包装器,与要显示的全区域按钮的父级匹配。
  • LinearLayout 按钮包装器,匹配父项。
  • Button 高度全部设置为 0dplayout_weight="1"
  • TextViews 用于水平居中但未垂直调整的 OR 圆。注意它们的直径是 30dp

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:id="@+id/buttons_container">
    
        <Button
            android:id="@+id/record_topic_option_1"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:onClick="topic1"
            android:theme="@style/PrimaryButton"/>
    
        <Button
            android:id="@+id/record_topic_option_2"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:layout_marginTop="4dp"
            android:layout_marginBottom="4dp"
            android:onClick="topic2"
            android:theme="@style/PrimaryButton" />
    
        <Button
            android:id="@+id/record_topic_option_3"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:onClick="topic3"
            android:theme="@style/PrimaryButton" />
    </LinearLayout>
    
    <TextView
        android:id="@+id/top_or"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:textAlignment="center"
        android:text="OR"
        android:layout_gravity="center_horizontal"
        android:gravity="center"
        android:textSize="@dimen/material_text_caption"
        android:textColor="@android:color/white"
        android:background="@drawable/or_circle_background"
        />
    
    <TextView
        android:id="@+id/bottom_or"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:textAlignment="center"
        android:layout_gravity="center_horizontal"
        android:gravity="center"
        android:text="OR"
        android:textSize="@dimen/material_text_caption"
        android:textColor="@android:color/white"
        android:background="@drawable/or_circle_background" />
    

设置完成后,诀窍是在 onCreate()

中以编程方式调整圆圈
final View buttonContainer = findViewById(R.id.buttons_container);
View topOr = findViewById(R.id.top_or);
View bottomOr = findViewById(R.id.bottom_or);

//Get the 15dp radius in pixels at the current screen density.
final int added_height_for_radius = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
15, getResources().getDisplayMetrics());

//Use a ViewTreeObserver to make sure that the view is drawn and you get an accurate measurement of the LinearLayout with buttons
buttonContainer.getViewTreeObserver().addOnGlobalLayoutListener(
        new ViewTreeObserver.OnGlobalLayoutListener() {
    @SuppressLint("NewApi")
    @SuppressWarnings("deprecation")
    @Override
    public void onGlobalLayout() {
        int width = buttonContainer.getWidth();
        int height = buttonContainer.getHeight();

        //Moving the topOr and bottomOr by setting the top margin to height/3-radius and 2*height/3-radius
        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams)topOr.getLayoutParams();
        params.setMargins(0, (height/3)-added_height_for_radius, 0, 0);
        topOr.setLayoutParams(params);

        FrameLayout.LayoutParams params2 = (FrameLayout.LayoutParams)bottomOr.getLayoutParams();
        params2.setMargins(0, (2*height/3)-added_height_for_radius, 0, 0);
        bottomOr.setLayoutParams(params2);
        buttonContainer.getViewTreeObserver().removeOnGlobalLayoutListener(this);
    }
});

感谢 Get height and width of a layout programmatically

我按照xml编码并生成了类似的输出

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

    <LinearLayout android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:weightSum="3"
        android:gravity="center"
         >

        <TextView
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:text="dd"
            android:background="#CCCCCC"
            android:gravity="center"
            android:layout_margin="5dp"
            android:layout_weight="1"/>



        <TextView
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:text="dd"
            android:layout_margin="5dp"
            android:background="#CCCCCC"
            android:gravity="center"
            android:layout_weight="1"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_margin="5dp"
            android:text="dd"
            android:background="#CCCCCC"
            android:gravity="center"
            android:layout_weight="1"/>

    </LinearLayout>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:weightSum="3"
        android:gravity="center"
        android:layout_height="match_parent">


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:gravity="center"
            android:orientation="vertical">
            <TextView
                android:layout_width="30dp"
                android:background="#000000"
                android:text="OR"
                android:textColor="#FFFFFF"
                android:gravity="center"
                android:layout_height="30dp" />
        </LinearLayout>


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:gravity="center"
            android:orientation="vertical">
            <TextView
                android:layout_width="30dp"
                android:background="#000000"
                android:text="OR"
                android:textColor="#FFFFFF"
                android:gravity="center"
                android:layout_height="30dp" />
        </LinearLayout>



    </LinearLayout>

</FrameLayout>