0

I am trying to make three buttons equally-spaced and aligned vertically with circles overlapping between them like so:

Three buttons with circles between them

I ran into difficulties because a LinearLayout was needed to equally weight the three buttons, but overlapping views are most easily done in RelativeLayout and FrameLayout (I need to support <21 SDK, so I can't use z-index with LinearLayout).

When I put the "OR" circles in the Frame/RelativeLayouts, there's no easy way to set them at 1/3rd the view height so that they fall in between the buttons.

How do I divide a FrameLayout with the OR circles into thirds to properly place the circles?

aterbo
  • 432
  • 7
  • 24
  • I almost had it with PercentRelativeLayout and negative margins for the "or"s, but even with code I still couldn't get those buggers to show up in front of the buttons. – kris larson Oct 13 '16 at 18:28
  • Huh, I've never used PercentRelativeLayout... As long as the the top most view in the display is at the bottom of the RelativeLayout, it should be displayed on top? – aterbo Oct 13 '16 at 18:33
  • That's what I did, but they were still underneath the buttons anyway. I think it has to do with the fact that the buttons are clickable and the textviews aren't. I even tried `bringToFront()` but couldn't make it work. – kris larson Oct 13 '16 at 18:40

2 Answers2

1

I have did following xml coding and generate similar out put

    <?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>

enter image description here

Miral Bhalani
  • 274
  • 2
  • 9
0

I couldn't find a straightforward solution to this, so I'm answering my own question! Please let me know if you have a better solution.

The solution I came up with was to layout the buttons in a LinearLayout inside a FrameLayout and weight them properly. The OR circles are placed in the FrameLayout after the buttons, so that they will be drawn on top. However, they are not positioned in the xml.

In onCreate() I measured the drawn size of the LinearLayout with buttons and then moved the OR circles by one third plus the radius of the circle.

Here is the relevant XML. The key points are:

  • FrameLayout wrapper, matching parent for full area buttons to be shown.
  • LinearLayout wrapper for buttons, matching parent.
  • Button heights all set to 0dp and layout_weight="1"
  • TextViews for OR circles centered horizontally, but not adjusted vertically. Note their diameter is 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" />
    

Once that is set up, the trick is to adjust the circles programmatically in 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);
    }
});

Thanks to Get height and width of a layout programmatically

Community
  • 1
  • 1
aterbo
  • 432
  • 7
  • 24