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