材料设计带边框的按钮

75

我知道如何制作具有填充颜色的Material Design按钮:

style="@style/Widget.AppCompat.Button.Colored"

无边框透明按钮:

style="@style/Widget.AppCompat.Button.Borderless.Colored"

但是,有没有办法制作出材料设计的带边框(内部透明)按钮?类似下面这样:

输入图像描述

10个回答

156

你也可以使用Material Components for Android

依赖项添加到你的build.gradle文件中:

dependencies { implementation 'com.google.android.material:material:1.3.0' }

在这种情况下,您可以在布局文件中使用MaterialButton

<com.google.android.material.button.MaterialButton
   ....
   style="@style/Widget.MaterialComponents.Button.OutlinedButton"
   app:cornerRadius=".."
   app:strokeColor="@color/colorPrimary"/>

应用样式@style/Widget.MaterialComponents.Button.OutlinedButton

在您的情况下,使用app:cornerRadius属性来更改角半径的大小。这将按指定尺寸使角变圆。
使用app:strokeColorapp:strokeWidth属性来更改边框的颜色和宽度。
enter image description here

您还可以使用ShapeApperance自定义角(需要版本1.1.0)。

<style name="MyButton" parent="Widget.MaterialComponents.Button.OutlinedButton">
    <item name="shapeAppearanceOverlay">@style/MyShapeAppearance</item>
</style>
<style name="MyShapeAppearance" parent="">
    <item name="cornerFamilyTopLeft">rounded</item>
    <item name="cornerFamilyBottomLeft">rounded</item>
    <item name="cornerFamilyTopRight">cut</item>
    <item name="cornerFamilyBottomRight">cut</item>
    <item name="cornerSize">8dp</item>
</style>

官方文档在这里,所有的 Android 规范在这里


使用 Jetpack Compose,您可以使用OutlinedButtonborder属性:

    OutlinedButton(
        onClick = { },
        border = BorderStroke(1.dp, Color.Blue),
        shape = RoundedCornerShape(8.dp) 
    ) {
        Text(text = "Save")
    }

输入图片说明


OLD (支持库)

使用新的Support Library 28.0.0 版本,Design Library 包含了 Material Button

您可以在布局文件中添加此按钮:

<android.support.design.button.MaterialButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="XXXX"
    android:textSize="18sp"
    app:icon="@drawable/ic_android_white_24dp" />

您可以使用以下属性自定义按钮:

  • app:backgroundTint:用于对按钮背景应用着色。如果您想更改按钮的背景颜色,请改用此属性而不是background。

  • app:strokeColor:用于按钮描边的颜色

  • app:strokeWidth:用于按钮描边的宽度

另外


33

以下是正确的操作步骤:

需要做的事情是:

1 - 创建带描边的形状drawable
2 - 创建水波纹drawable
3 - 为低于v21版本创建选择器drawable
4 - 为带边框的按钮创建新样式
5 - 在按钮上应用该样式

1 - 创建带描边的形状 btn_outline.xml

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <stroke
        android:width="2dp"
        android:color="@color/colorAccent">
    </stroke>
    <solid android:color="@color/colorTransparent"/>
    <corners
        android:radius="5dp">
    </corners>

</shape>

2 - 创建涟漪可绘制物 drawable-v21/bg_btn_outline.xml

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="@color/colorOverlay">
    <item>
        <shape>
            <stroke
                android:width="2dp"
                android:color="@color/colorAccent"/>
            <corners android:radius="5dp"/>
        </shape>
    </item>
    <item android:id="@android:id/mask">
        <shape>
            <stroke
                android:width="2dp"
                android:color="@color/colorAccent"/>
            <solid android:color="@android:color/white"/>
            <corners android:radius="5dp"/>
        </shape>
    </item>

</ripple>

android:id="@android:id/mask"是必需的,以便在按钮上具有涟漪触摸反馈。标记为遮罩的图层在屏幕上不可见,仅用于触摸反馈。

3-创建小于v21版本的选择器可绘制对象 drawable/bg_btn_outline.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/btn_outline" android:state_pressed="true">
        <shape android:shape="rectangle">
            <solid android:color="@color/colorOverlay"/>
        </shape>
    </item>
    <item android:drawable="@drawable/btn_outline" android:state_focused="true">
        <shape android:shape="rectangle">
            <solid android:color="@color/colorOverlay"/>
        </shape>
    </item>

    <item android:drawable="@drawable/btn_outline"/>

</selector>

4 - 创建具有边框的按钮的新样式 给出了创建该样式所需的所有资源,您的样式应如下所示。

<style name="ButtonBorder" parent="Widget.AppCompat.Button.Colored"/>

<style name="ButtonBorder.Accent">
        <item name="android:background">@drawable/bg_btn_outline</item>
        <item name="android:textColor">@color/colorAccent</item>
        <item name="android:textAllCaps">false</item>
        <item name="android:textSize">16sp</item>
        <item name="android:singleLine">true</item>
    </style>

4 - 给按钮应用样式

<Button
   style="@style/ButtonBorder.Accent"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"/>

就是这样。以下是按钮现在的样子示例。 enter image description here


你是在drawable还是drawable-v21文件夹中创建btn_outline.xml文件的? - AG-Developer

6

您可以通过将Material Design按钮的样式属性设置为@style/Widget.MaterialComponents.Button.OutlinedButton并将app:strokeColor属性值设置为首选颜色来轻松实现此操作。

示例:

<com.google.android.material.button.MaterialButton
                android:text="Rounded outlined button"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:id="@+id/btnRound"
                style="@style/Widget.MaterialComponents.Button.OutlinedButton"
                app:strokeColor="@color/colorPrimaryDark"/>

References:


4
感谢@NomanRafique提供了详细的答案!然而,由于自定义背景,我们失去了一些重要的东西:
  1. 按钮的高度比默认的Widget.AppCompat.Button大
  2. 内边距
  3. 启用/禁用状态
如果您想知道,默认背景是什么样子的,可以看这里:https://android.googlesource.com/platform/frameworks/support/+/a7487e7/v7/appcompat/res/drawable-v21/abc_btn_colored_material.xml 通过重复使用原始插图、填充和颜色选择器,在简单的情况下,我们可以得到像这样的东西(所有的值都是默认的,并来自于Android Support/Material Library): drawable-v21/bg_btn_outlined.xml
<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">
    <ripple xmlns:android="http://schemas.android.com/apk/res/android"
            android:color="?attr/colorControlHighlight">
        <item>
            <shape>
                <stroke
                    android:width="2dp"
                    android:color="@color/abc_btn_colored_borderless_text_material"/>
                <corners android:radius="@dimen/abc_control_corner_material"/>
                <padding
                    android:bottom="@dimen/abc_button_padding_vertical_material"
                    android:left="@dimen/abc_button_padding_horizontal_material"
                    android:right="@dimen/abc_button_padding_horizontal_material"
                    android:top="@dimen/abc_button_padding_vertical_material"/>
            </shape>
        </item>
        <item android:id="@android:id/mask">
            <shape>
                <stroke
                    android:width="2dp"
                    android:color="@color/abc_btn_colored_borderless_text_material"/>
                <solid android:color="@android:color/white"/>
                <corners android:radius="@dimen/abc_control_corner_material"/>
            </shape>
        </item>
    </ripple>
</inset>

styles.xml

<style name="Button.Outlined" parent="Widget.AppCompat.Button.Borderless.Colored">
    <item name="android:background">@drawable/bg_btn_outlined</item>
</style>

此时,我们应该有一个轮廓化的按钮,可以响应触摸事件,尊重enabled="false"状态,并且与默认的Widget.AppCompat.Button具有相同的高度:

enter image description here

现在,您可以通过提供自己的实现来开始自定义颜色@color/abc_btn_colored_borderless_text_material 颜色选择器。

3
在你的XML中使用这个:
            <com.google.android.material.button.MaterialButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Its a button"
                android:textColor="@android:color/white"
                android:textSize="@dimen/_12ssp"
                app:backgroundTint="@android:color/transparent"
                app:strokeColor="@android:color/white"
                app:strokeWidth="@dimen/_1sdp" />

其中

  1. app:backgroundTint 用于设置背景色
  2. app:strokeColor 用于设置边框颜色
  3. app:strokeWidth 用于设置边框宽度

2

以下是我如何在Lollipop及以上版本中只使用边框和涟漪效果来创建按钮的方法。就像AppCompat按钮一样,这些按钮在低版本API上有一个回退的按下效果(如果您需要在低版本API上实现涟漪效果,则需要使用外部库)。我使用FrameLayout因为它很便宜。文本和边框的颜色是黑色,但您可以通过自定义来更改它:

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="20dp"
    android:background="@drawable/background_button_ghost">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?android:selectableItemBackground"
        android:gravity="center"
        android:padding="14dp"
        android:textSize="16sp"
        android:textAllCaps="true"
        android:textStyle="bold"
        android:textColor="@android:color/black"
        android:text="Text"/>
</FrameLayout>

drawable/background_button_ghost.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <stroke
        android:width="2dp"
        android:color="@android:color/black"/>
    <solid android:color="@color/transparent"/>
</shape>

如果我漏掉了某些内容,请留下评论,我会更新答案。

是的,我想避免混乱的自定义实现。但我想我别无选择。 - jclova
你可以将它作为自定义类,这是我目前使用的最佳方式,因为在xml中声明更短。 - Galya

2

只需使用带有轮廓样式的MaterialButton

<com.google.android.material.button.MaterialButton
    ...
    style="@style/Widget.MaterialComponents.Button.OutlinedButton"
    android:text="Delete Mentor Manager"
    app:strokeColor="@color/...."
    app:strokeWidth="1dp" />

1

你也可以使用Jetpack Compose来完成这个操作。只需要创建一个包含OutlinedButton的组合函数,并将所需的边框作为参数传递:

@Composable
fun OutlineButton() {
    OutlinedButton(
        onClick = { //TODO - implement click here },
        border = BorderStroke(1.dp, Color.Blue), // <-- border property
        shape = RoundedCornerShape(corner = CornerSize(20.dp)),
        colors = ButtonDefaults.outlinedButtonColors(contentColor = Color.Blue)
    ){
        Text(text = "CONFIRM")
    }
}

0

简单地,您可以使用这段代码。它看起来非常不错。

           <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="#ffffff"
                android:orientation="vertical">

                <android.support.v7.widget.AppCompatButton
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:backgroundTint="#F48025"
                    android:text="login"
                    android:textColor="@color/colorWhite" />

            </LinearLayout>

这里的边框颜色是:

android:background="#ffffff"

背景颜色为:

android:backgroundTint="#F48025"

1
你的解决方案很简单但是有限制。你无法控制边框的厚度,而且边框内部是圆形但外部是有棱角的。看起来不太好看。 - jclova
在我的情况下,按钮是透明的。 - IgniteCoders

-1
<Button
    android:id="@+id/btn_add_discussion"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginHorizontal="15dp"
    android:padding="8dp"
    android:layout_marginTop="10dp"
    android:layout_marginBottom="5dp"
    android:backgroundTint="#80ffffff"
    android:textColor="@color/colorPrimaryDark"
    style="@style/btn_start_new_discussion"
    android:text="Start new discussion" />

将以下代码放入Styles.xml文件中:
<style name="btn_start_new_discussion">
    <item name="android:layout_marginTop">15dp</item>
    <item name="strokeWidth">2dp</item>
    <item name="strokeColor">@color/colorPrimary</item>
    <item name="cornerRadius">10dp</item>
</style>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接