【问题标题】:Material design button with border带边框的材料设计按钮
【发布时间】:2016-09-20 14:41:03
【问题描述】:

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

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

无边框透明按钮:

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

但是,有没有办法让 Material design 有边框(内部透明)按钮?像下面这样的?

【问题讨论】:

    标签: android button material-design android-button material-components-android


    【解决方案1】:

    您也可以使用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 属性来更改拐角半径的大小。这将圆角指定尺寸。
    使用 te 属性 app:strokeColorapp: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 和所有的android 规格here


    使用 jetpack compose 1.0.x 您可以使用 OutlinedButtonborder 属性:

        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: 按钮描边的宽度

    还有

    【讨论】:

      【解决方案2】:

      这里是如何正确地做到这一点。

      你需要做的是

      1 - 使用描边创建可绘制形状
      2 - 创建波纹可绘制
      3 - 创建小于 v21 的可绘制选择器
      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"/>
      

      差不多就是这样。这是按钮现在的外观示例。

      【讨论】:

      • 您在哪里创建 btn_outline.xml ,在 drawable 或 drawable-v21 中??
      【解决方案3】:

      您可以通过将 Material Design Button 的 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"/>
      

      参考资料:

      【讨论】:

        【解决方案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 支持/材质库): p>

        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 颜色选择器实现。

        【讨论】:

          【解决方案5】:

          在你的 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 是边框宽度

          【讨论】:

            【解决方案6】:

            这就是我如何在 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>
            

            如果我遗漏了什么,请发表评论,我会更新答案。

            【讨论】:

            • 是的,我想避免混乱的自定义实现。但我想我别无选择。
            • 你可以将它作为一个自定义类,这是我遇到的最好的,我现在正在使用它,因为它在 xml 中的声明更短。
            【解决方案7】:

            只需您可以使用此代码。 它看起来太好了。

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

            【讨论】:

            • 您的解决方案简单但有限。您无法控制边框的厚度,并且边框内部是圆形的,但外部是边缘的。不好看。
            • 在我的例子中,按钮是透明的
            【解决方案8】:

            您也可以使用 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")
                }
            }
            

            【讨论】:

              【解决方案9】:
              <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>
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2023-04-05
                • 2016-06-28
                • 2015-01-04
                • 2016-01-12
                • 1970-01-01
                • 1970-01-01
                • 2020-04-14
                • 1970-01-01
                相关资源
                最近更新 更多