简体   繁体   中英

How to align Material buttons with other UI elements

I have trouble to align default material buttons with other elements of the UI. In fact I have looked at the Android source code and the background for the buttons contains insets to be able to draw the shadow and deal with the elevation of the button when clicked:

<inset xmlns:android="http://schemas.android.com/apk/res/android"
   android:insetLeft="@dimen/abc_button_inset_horizontal_material"
   android:insetTop="@dimen/abc_button_inset_vertical_material"
   android:insetRight="@dimen/abc_button_inset_horizontal_material"
   android:insetBottom="@dimen/abc_button_inset_vertical_material">
   <shape android:shape="rectangle">
        <corners android:radius="@dimen/abc_control_corner_material" />
        <solid android:color="@android:color/white" />
        <padding android:left="@dimen/abc_button_padding_horizontal_material"
             android:top="@dimen/abc_button_padding_vertical_material"
             android:right="@dimen/abc_button_padding_horizontal_material"
             android:bottom="@dimen/abc_button_padding_vertical_material" />
    </shape>
</inset>

So, I have the very basic layout below:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp"
    >
    <View
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:background="#123456"
        />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="test button alignment"
        />
    <View
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:background="#123456"
        />
</LinearLayout>

And as you can see, the left edge of the button is not aligned with the left edges of the other views.

在此输入图像描述

So my question is, is there a way to get rid of these insets without loosing the shadow/elevation handled out of the box by default Android buttons to have the UI well aligned?

Thanks!

There's also hit area thing involved. Buttons have larger clickable area than the graphics.

Your layout already has padding, so the button will easily have space to draw shadow. All you have to do is to remove horizontal insets from button's background.

The general case is more complex. You should:

  • remove insets from button's background,
  • remember to always add some padding/margin around your widgets to leave space for shadows,
  • extend hit rect to capture clicks in entire clickable area.

First two things are simple, the last point can be done using for example getHitRect():

 public void getHitRect(@NonNull Rect outRect) { 
     if (touchMargin == null) { 
         super.getHitRect(outRect); 
         return; 
     } 
     outRect.set(getLeft() - touchMargin.left, getTop() - touchMargin.top, getRight() + touchMargin.right, getBottom() + touchMargin.bottom); 
 } 

Your case is also very easy to solve using Carbon (which does pretty much what I wrote - removes insets, adds custom hit rect):

<?xml version="1.0" encoding="utf-8"?>
<carbon.widget.LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <View
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:background="#123456" />

    <carbon.widget.Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginTop="8dp"
        android:text="test button alignment" />

    <View
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:background="#123456" />
</carbon.widget.LinearLayout>

在此输入图像描述

And here's how it looks with debug mode on. Red lines show extended hit rect. Green lines are view bounds.

在此输入图像描述

please review the following xml, I added to value android:layout_marginLeft="-4dip"

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">

<View
    android:id="@+id/te"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:background="#123456" />

<Button
    android:id="@+id/bu"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/te"
    android:text="test button alignment"
    android:layout_marginLeft="-4dip"
    />

<View
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:background="#123456"
    android:layout_below="@+id/bu"
    />
</RelativeLayout>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM