如何正确删除Android中按钮周围的填充(或边距?)?

时间:2017-04-03 19:03:29

标签: java android android-layout android-view android-button

目前,我有以下底部登录按钮。

未按下按钮时

enter image description here

按下按钮时

enter image description here

XML看起来像这样

<LinearLayout
    android:background="?attr/welcomeBottomNavBarBackground"
    android:orientation="horizontal"
    android:id="@+id/sign_in_bottom_nav_bar"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true">
    <Button
        style="?android:attr/buttonBarButtonStyle"
        android:id="@+id/sign_in_button"
        android:layout_width="0dp"
        android:width="0dp"
        android:layout_weight="1.0"
        android:layout_height="48dp"
        android:gravity="center"
        android:layout_gravity="center"
        android:enabled="true"
        android:textAllCaps="true"
        android:text="@string/log_in" />
</LinearLayout>

我想在按下按钮时删除填充(或者我应该将其称为边距?请参阅我最底层的p / s部分)。

我看How to remove padding around buttons in Android?

我曾尝试过

<Button
    ...
    ...
    android:minHeight="0dp"
    android:minWidth="0dp" />

它没有效果,也没有效果。

我进一步尝试

<Button
    ...
    ...
    android:background="@null"
    android:minHeight="0dp"
    android:minWidth="0dp" />

按下时不再填充。然而,设计压制视觉效果的材料也将消失。

我是否知道在按下按钮时删除按钮填充的最佳方法是什么,同时保留材料设计按下的视觉效果?

P / S

我真的不知道是否应该称之为填充或边距。我希望实现的是,当我们按下底部区域时,按下视觉效果变化应该覆盖整个100%底栏区域(@+id/sign_in_bottom_nav_bar),而不是当前95%的底栏区域。

13 个答案:

答案 0 :(得分:21)

标准按钮不应该用于全宽,这就是您遇到此问题的原因。

背景

如果您查看Material Design - Button Style,您会看到一个按钮的高度点击区域为48dp,但由于某种原因,它将显示为36dp的高度。

这是您看到的背景轮廓,它不会覆盖按钮本身的整个区域 它有圆角和一些填充,应该可以自己点击,包裹它的内容,而不是跨越屏幕底部的整个宽度。

解决方案

如上所述,你想要的是一个不同的背景。不是标准按钮,而是可选项目的背景,具有良好的连锁效果。

对于此用例,您可以使用?selectableItemBackground主题属性作为背景(尤其是列表)。
它将添加平台标准波纹(或某些颜色状态列表&lt; 21)并将使用您当前的主题颜色。

对于您的用例,您可以使用以下内容:

<Button
    android:id="@+id/sign_in_button"
    style="?android:attr/buttonBarButtonStyle"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Login"
    android:background="?attr/selectableItemBackground" />
                   <!--  /\ that's all -->

如果您的视图是唯一的视图并跨越整个屏幕,则无需添加布局权重

如果你对背景看起来有什么不同的想法,你必须自己创建一个自定义绘图,并在那里管理颜色和状态。

答案 1 :(得分:4)

styles.xml

<style name="MyButtonStyle" parent="Base.Widget.AppCompat.Button">
    <item name="android:background">@drawable/selector</item>
    <item name="android:textColor">@android:color/black</item>
</style>

values/drawable

<强> my_drawable.xml

<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="2dp" />
    <!-- specify your desired color here -->
    <solid android:color="#9e9b99" />
</shape>

<强> selector.xml

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

values/drawable-v21

<强> my_drawable.xml

<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle"
       android:tint="?attr/colorButtonNormal"
       xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="2dp" />
    <solid android:color="@android:color/white" />
</shape>

<强> selector.xml

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="?attr/colorControlHighlight">
    <item android:id="@android:id/mask"
          android:drawable="@drawable/my_drawable" />
</ripple>

布局:

<Button
    android:id="@+id/button"
    style="@style/MyButtonStyle"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:text="Test"/>

API 19上的结果:

enter image description here

API 21上的结果:

enter image description here

Source code

答案 2 :(得分:2)

我认为解决这个问题的最佳解决方案是创建自己的Ripple Effect。按下按钮时的填充符合组件的默认Ripple Effect

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="?attr/colorControlHighlight">
    <item android:drawable="?attr/colorPrimary"/>
</ripple>

或者您可以尝试将按钮的样式更改为style="?android:textAppearanceSmall"

请记住:此效果仅显示在Android Lollipop (API 21)或更高版本。

答案 3 :(得分:2)

我经历过你正在经历的事情。简而言之,您只能单独使用<Button>标签干净利落,同时确保向后兼容性。

最简单且应用最广泛的方法是在<RelativeLayout>附近使用<Button>参考地址。

按键代码:

        <RelativeLayout
            android:id="@+id/myButtonUnderlay"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/colorPrimary"
            android:visibility="visible">

            <Button
                android:id="@+id/myButton"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="?attr/selectableItemBackgroundBorderless"
                android:text="I am as cute as a Button"/>

        </RelativeLayout>

无论您何时需要使用按钮,都可以使用此完整代码。

以下是细分:

  1. OnClick事件将挂钩到myButton
  2. 通过更改myButtonUnderlay
  3. 的属性来控制按钮的尺寸
  4. myButtonandroid:background="?attr/selectableItemBackgroundBorderless"。这将使它成为一个透明按钮,只有文本和向后兼容的涟漪。
  5. myButtonUnderlay中,您将执行所有其他背景应用程序,例如设置按钮的颜色,边距,填充,边框,渐变和阴影等。
  6. 如果希望操纵按钮的可见性(程序化与否),请在myButtonUnderlay上进行。
  7. 注意:为确保向后兼容性,请确保使用

    android:background="?attr/selectableItemBackgroundBorderless"

    android:background="?android:attr/selectableItemBackgroundBorderless"

答案 4 :(得分:1)

作为@David Medenjak的回答,您可以在其开发者网站上阅读Google Material design Button-style。使用按钮样式@David Medenjak在他的回答中解释。您也可以通过以下方式进行操作 它不是填充或边距,但它实际上是按钮的背景效果。 如果你想删除它,那么你可以这样做。

  

选项1:

步骤1:将以下代码放在styles.xml

<style name="myColoredButton">
        <item name="android:textColor">#FF3E96</item>
        <item name="android:padding">0dp</item>
        <item name="android:minWidth">88dp</item>
        <item name="android:minHeight">36dp</item>
        <item name="android:elevation">1dp</item>
        <item name="android:translationZ">1dp</item>
        <item name="android:background">#FF0000</item>
    </style>

步骤2:在drawables文件夹下创建一个新的XML文件并添加以下代码:我将我的XML文件命名为button_prime.xml

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/colorPrimary">
    <item>
        <shape xmlns:android="http://schemas.android.com/apk/res/android">
            <corners android:radius="1dp" />
            <solid android:color="#8B8386" />
        </shape>
    </item>
</ripple>

步骤3:使用Button中的样式和drawable,如下所示。

<Button
        style="@style/myColoredButton"
        android:layout_width="250dp"
        android:layout_height="50dp"
        android:text="Cancel"
        android:gravity="center"
        android:background="@drawable/button_prime"
        android:colorButtonNormal="#3578A9" />
  

选项2:

使用支持库v7,所有样式实际上已经定义并可以使用,对于标准按钮,所有这些样式都可用。所以你可以像这样设置按钮样式

<Button
    style="@style/Widget.AppCompat.Button.Borderless"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:text="BUTTON"
    android:gravity="center"
    android:minHeight="0dp"
    android:minWidth="0dp"
    android:background="@color/colorAccent"/>

有关按钮样式的详细信息,请check 此回答

我想你也会检查this answer。我希望你能得到解决方案。

答案 5 :(得分:1)

填充和边距可能是按钮中使用的原始资源的结果。

因此,您可以尝试使用选择器更改所使用的资源:

<selector
  xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/btn_action_hover" />
    <item android:state_selected="true" android:drawable="@drawable/btn_action_hover" />
    <item android:state_focused="true" android:drawable="@drawable/btn_action_hover" />
    <item android:drawable="@drawable/btn_action_normal" />
</selector>

这将改变按钮的默认图像/形状,因此您可以尝试使用drawable并将每个项目设置为drawable。 drawable可以是位图,也可以是.xml文件(样式文件),用于定义当前状态下按钮的外观。我认为即使你自己设置了按钮式,仍然会包含一些原生样式。这可能是因为您没有使用自定义主题。所以这个问题也可以通过defing来解决

theme="@style/myNewTheme"

myNewTheme是你的主题,它应该有任何父母(parent=""不应该被定义)。

采用任何给定的主题(由Google / Android设计,对于一个实例Theme.AppCompat。[name]),它也带有一个buttonStyle。这是Theme.Holo.Light的一部分:

    <!-- Button styles -->
    <item name="buttonStyle">@style/Widget.Holo.Light.Button</item>

    <item name="buttonStyleSmall">@style/Widget.Holo.Light.Button.Small</item>
    <item name="buttonStyleInset">@style/Widget.Holo.Light.Button.Inset</item>

    <item name="buttonStyleToggle">@style/Widget.Holo.Light.Button.Toggle</item>
    <item name="switchStyle">@style/Widget.Holo.Light.CompoundButton.Switch</item>
    <item name="mediaRouteButtonStyle">@style/Widget.Holo.Light.MediaRouteButton</item>

    <item name="selectableItemBackground">@drawable/item_background_holo_light</item>
    <item name="selectableItemBackgroundBorderless">?attr/selectableItemBackground</item>
    <item name="borderlessButtonStyle">@style/Widget.Holo.Light.Button.Borderless</item>
    <item name="homeAsUpIndicator">@drawable/ic_ab_back_holo_light</item>

如您所见,此主题定义了按钮在基本功能中的外观/工作方式。你可以覆盖它的一部分,但你没有覆盖重要的部分(是buttonStyle和类似的)。因此,如果您自己创建一个新主题并根据自己的喜好设置它并设置主题(使用theme =“themename”)并且该主题不会继承任何主题,您应该能够根据自己的喜好设置按钮的样式而不必担心关于主题中的默认样式

基本上:

调用padding / margin =“0dp”无济于事。主题定义的默认drawable在按钮drawable中具有此功能,这意味着您无法更改它。因此,您必须更改按钮样式,或完全更改主题。确保主题没有任何父项,因为许多主题定义了按钮样式。您不希望主题定义按钮样式。

答案 6 :(得分:0)

我建议您先查看this以防万一。

然后,如果没有工作,我建议您使用android xml drawables创建自己的样式(如azizbekian建议),并使用可绘制状态来区分压缩/未压缩。

我认为使用自己的风格可能是最好的答案,因为它可以进一步让您更好地控制应用程序的显示方式,但使用Android默认主题和样式也允许用户拥有自定义样式,这是一个好主意。但是,您无法测试每个自定义样式,因此您无法检查您的应用程序是否会在所有自定义样式上正确显示,因此可能会遇到一些问题。

答案 7 :(得分:0)

Button背景设为android:background="?selectableItemBackground"

<LinearLayout
    android:background="?attr/welcomeBottomNavBarBackground"
    android:orientation="horizontal"
    android:id="@+id/sign_in_bottom_nav_bar"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true">

    <Button
        style="?android:attr/buttonBarButtonStyle"
        android:background="?selectableItemBackground"
        android:id="@+id/sign_in_button"
        android:layout_width="0dp"
        android:width="0dp"
        android:layout_weight="1.0"
        android:layout_height="48dp"
        android:gravity="center"
        android:layout_gravity="center"
        android:enabled="true"
        android:textAllCaps="true"
        android:text="@string/log_in" />

</LinearLayout>

答案 8 :(得分:0)

尝试了许多解决方案后,最后我得出一个结论,仅凭标签就无法实现这一目标。删除按钮周围不必要的空间,我的解决方法如下:

 <RelativeLayout
    android:id="@+id/myButtonUnderlay"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:visibility="visible">
<Button
    android:id="@+id/save_button"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:layout_marginTop="-5dp" 
    android:layout_marginBottom="-5dp"
    android:layout_above="@+id/content_scrollview"
    android:layout_gravity="bottom"
    android:background="@drawable/ripple_theme"
    android:enabled="true"
    android:text="SetUp Store"
    android:textColor="#fff"
    android:textSize="18sp"
    android:visibility="gone"
    tools:visibility="visible"
    style="@style/MediumFontTextView" />
</RelativeLayout>

答案 9 :(得分:0)

很简单,使用inset属性,如:

android:insetTop="0dp"
android:insetBottom="0dp"
android:insetRight="0dp"
android:insetLeft="0dp"

答案 10 :(得分:0)

当今最好的解决方案是仅使用MaterialButton代替Button

  

注意:MaterialButton在外观上与Button和AppCompatButton不同。主要区别之一是AppCompatButton的左右两侧具有4dp插图,而MaterialButton没有。要添加与AppCompatButton匹配的插图,请将按钮上的android:insetLeft和android:insetRight设置为4dp,或更改按钮的父级布局上的间距。

     

用MaterialButton替换应用中的按钮时,应检查这些更改的大小和间距差异。

来源:https://material.io/develop/android/components/material-button/

答案 11 :(得分:-2)

1.添加一个名为maybe_background.xml的可绘制资源文件

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <shape>
            <solid android:color="#ff0000"/>
            <stroke android:width="5dp" android:color="#00ff00"/>
        </shape>
    </item>
    <item>
        <shape>
            <solid android:color="#00ff00"/>
        </shape>
    </item>
</selector>

2.使用button_background.xml作为按钮背景,完成!

github

blog

答案 12 :(得分:-2)

  

我真的不知道是否应该将其称为填充或边距。

按钮正在制作表面高度,以提供响应触摸的视觉反馈。这是用于surface reaction的两个反馈之一;第一个是涟漪效应。例如,凸起按钮的静止状态高度为2dp,按下状态高度为8dp(请参阅Shadows下的凸起按钮)。当按钮接触表面时,按钮会与手指相接触。

  

我是否知道在按下按钮时删除按钮填充的最佳方法是什么,同时保留材料设计按下的视觉效果?

回答完第一部分后,如果您想要消除表面高程效果,我不相信您拥有所有的材料设计。

无论如何,这里是如何删除表面高程视觉反馈:

将动画文件button_raise.xml添加到 res 目录下的 animator 目录,其中包含以下代码:

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

    <item
        android:state_enabled="true"
        android:state_pressed="true">

        <objectAnimator
            android:duration="@android:integer/config_shortAnimTime"
            android:propertyName="translationZ"
            android:valueTo="0dp"
            android:valueType="floatType" />
    </item>
</selector>

使用stateListAnimator属性

在按钮中引用新创建的动画师
<Button
    ...
    android:stateListAnimator="@animator/button_raise"
    ... />

希望这有帮助。