Material 带边框的设计按钮
Material design button with border
我知道如何制作 Material 带有颜色填充的设计按钮:
style="@style/Widget.AppCompat.Button.Colored"
无边框透明按钮:
style="@style/Widget.AppCompat.Button.Borderless.Colored"
但是,有没有办法让 Material 设计有边框(内部透明)的按钮?像下面这样的东西?
这就是我在 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>
如果我遗漏了什么,请发表评论,我会更新答案。
只需您就可以使用此代码。 看起来真不错。
<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 - 创建带描边的可绘制形状
2 - 创建波纹可绘制对象
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"/>
差不多就这些了。下面是按钮现在的外观示例。
您也可以使用 Material Components for Android。
将 the dependency 添加到您的 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:strokeColor
和 app:strokeWidth
改变边框的颜色和宽度。
您还可以使用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>
官方文档是here and all the android specs here。
使用 jetpack compose 1.0.x
你可以使用 OutlinedButton
和 border
属性:
OutlinedButton(
onClick = { },
border = BorderStroke(1.dp, Color.Blue),
shape = RoundedCornerShape(8.dp)
) {
Text(text = "Save")
}
OLD(支持图书馆)
有了新的 Support Library 28.0.0,设计库现在包含 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
: 用于对按钮的背景应用色调。如果您想更改按钮的背景颜色,请使用此属性而不是背景。
app:strokeColor
: 按钮描边要使用的颜色
app:strokeWidth
: 按钮描边的宽度
还有
感谢@NomanRafique 的详细解答!但是,由于自定义背景,我们丢失了一些重要的东西:
- 按钮的高度大于默认值
Widget.AppCompat.Button
- 填充
- Enable/Disable 状态
如果您想知道,这里是默认背景的样子:https://android.googlesource.com/platform/frameworks/support/+/a7487e7/v7/appcompat/res/drawable-v21/abc_btn_colored_material.xml
通过重复使用原始的插图、填充和颜色选择器,在一个简单的情况下,我们可以想出这样的东西(所有值都是默认值,来自 android support/material 图书馆) :
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
:
现在,您可以从这里开始自定义颜色,方法是提供您自己的 @color/abc_btn_colored_borderless_text_material
颜色选择器实现。
您可以通过将 Material 设计按钮的 style
属性设置为 @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"/>
参考文献:
在你的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" />
其中
- app:backgroundTint 用于背景色
- app:strokeColor 是边框颜色
- app:strokeWidth 是边框宽度
<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>
您也可以使用 Jetpack Compose 执行此操作。为此,只需创建一个带有 OutlinedButton 的可组合函数,并将 as 参数传递给您想要的边框:
@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")
}
}
我知道如何制作 Material 带有颜色填充的设计按钮:
style="@style/Widget.AppCompat.Button.Colored"
无边框透明按钮:
style="@style/Widget.AppCompat.Button.Borderless.Colored"
但是,有没有办法让 Material 设计有边框(内部透明)的按钮?像下面这样的东西?
这就是我在 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>
如果我遗漏了什么,请发表评论,我会更新答案。
只需您就可以使用此代码。 看起来真不错。
<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 - 创建带描边的可绘制形状
2 - 创建波纹可绘制对象
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"/>
差不多就这些了。下面是按钮现在的外观示例。
您也可以使用 Material Components for Android。
将 the dependency 添加到您的 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:strokeColor
和 app:strokeWidth
改变边框的颜色和宽度。
您还可以使用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>
官方文档是here and all the android specs here。
使用 jetpack compose 1.0.x
你可以使用 OutlinedButton
和 border
属性:
OutlinedButton(
onClick = { },
border = BorderStroke(1.dp, Color.Blue),
shape = RoundedCornerShape(8.dp)
) {
Text(text = "Save")
}
OLD(支持图书馆)
有了新的 Support Library 28.0.0,设计库现在包含 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
: 用于对按钮的背景应用色调。如果您想更改按钮的背景颜色,请使用此属性而不是背景。app:strokeColor
: 按钮描边要使用的颜色app:strokeWidth
: 按钮描边的宽度
还有
感谢@NomanRafique 的详细解答!但是,由于自定义背景,我们丢失了一些重要的东西:
- 按钮的高度大于默认值
Widget.AppCompat.Button
- 填充
- Enable/Disable 状态
如果您想知道,这里是默认背景的样子:https://android.googlesource.com/platform/frameworks/support/+/a7487e7/v7/appcompat/res/drawable-v21/abc_btn_colored_material.xml
通过重复使用原始的插图、填充和颜色选择器,在一个简单的情况下,我们可以想出这样的东西(所有值都是默认值,来自 android support/material 图书馆) :
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
:
现在,您可以从这里开始自定义颜色,方法是提供您自己的 @color/abc_btn_colored_borderless_text_material
颜色选择器实现。
您可以通过将 Material 设计按钮的 style
属性设置为 @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"/>
参考文献:
在你的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" />
其中
- app:backgroundTint 用于背景色
- app:strokeColor 是边框颜色
- app:strokeWidth 是边框宽度
<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>
您也可以使用 Jetpack Compose 执行此操作。为此,只需创建一个带有 OutlinedButton 的可组合函数,并将 as 参数传递给您想要的边框:
@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")
}
}