[英]How to properly remove padding (or margin?) around buttons in Android?
目前,我有以下底部登錄按鈕。
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 部分)。
我試過了
<Button
...
...
android:minHeight="0dp"
android:minWidth="0dp" />
它不起作用,也沒有效果。
我進一步嘗試
<Button
...
...
android:background="@null"
android:minHeight="0dp"
android:minWidth="0dp" />
按下時不再填充。 然而,材料設計的壓制視覺效果也會消失。
我可以知道在按下過程中刪除按鈕填充的最佳方法是什么,同時保留材料設計的按下視覺效果?
我真的不知道我應該稱之為填充還是邊距。 我希望實現的是,當我們按下底部區域時,按下視覺效果變化應該覆蓋整個 100% 底部欄區域( @+id/sign_in_bottom_nav_bar
),而不是當前 95% 底部欄區域。
標准按鈕不應該以全寬使用,這就是您遇到這種情況的原因。
如果您查看Material Design - Button Style,您將看到按鈕具有 48dp 高度的點擊區域,但出於某種原因將顯示為 36dp 的高度。
這是您看到的背景輪廓,它不會覆蓋按鈕本身的整個區域。
它有圓角和一些填充,並且應該可以自己點擊,包裹其內容,而不是跨越屏幕底部的整個寬度。
如上所述,您想要的是不同的背景。 不是標准按鈕,而是具有這種漂亮漣漪效果的可選項目的背景。
對於這個用例,有?selectableItemBackground
主題屬性,您可以將其用於背景(尤其是在列表中)。
它將添加一個平台標准波紋(或 < 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 -->
如果您的視圖是唯一的並且跨越整個屏幕,則也無需添加布局權重
如果你對背景應該是什么樣子有一些不同的想法,你必須自己創建一個自定義的可繪制對象,並在那里管理顏色和狀態。
很簡單,使用inset
屬性,如:
android:insetTop="0dp"
android:insetBottom="0dp"
android:insetRight="0dp"
android:insetLeft="0dp"
在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>
選擇器.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>
選擇器.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 上的結果:
API 21 的結果:
我認為解決這個問題的最佳解決方案是創建自己的Ripple Effect
。 按下按鈕時的填充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)
或更高版本上顯示。
我經歷過你正在經歷的事情。 長話短說,你不能單獨使用<Button>
標簽做到這一點,同時確保向后兼容性。
最簡單和最廣泛使用的方法是在<Button>
周圍使用<RelativeLayout>
底層。
按鈕代碼:
<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>
無論您需要在何處使用按鈕,都可以使用此完整代碼。
這是細分:
myButton
。myButtonUnderlay
屬性來控制按鈕的尺寸。myButton
, android:background="?attr/selectableItemBackgroundBorderless"
。 這將使它成為一個透明的按鈕,只有文本和向后兼容的漣漪。myButtonUnderlay
,您將執行所有其他后台應用程序,例如設置按鈕的顏色、邊距、填充、邊框、漸變和陰影等。myButtonUnderlay
。注意:為確保向后兼容,請確保您使用
android:background="?attr/selectableItemBackgroundBorderless"
,而不是
android:background="?android:attr/selectableItemBackgroundBorderless"
正如@David Medenjak 回答的那樣,您可以在其開發人員網站上閱讀 Google Material design Button-style 。 使用@David Medenjak 在他的回答中解釋的按鈕樣式。 您也可以通過以下方式進行它也不是填充或邊距,但它實際上是按鈕的背景效果。 如果您想刪除它,那么您可以執行以下操作。
選項1:
第 1 步:將下面的代碼放在 style.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 中使用樣式和可繪制對象。
<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"/>
有關按鈕樣式的更多詳細信息,請查看此答案
我想你也會檢查這個答案。 我希望你能得到你的解決方案。
填充和邊距可能是按鈕中使用的原始資源的結果。
因此,您可以嘗試使用選擇器更改使用的資源:
<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 可以是位圖,也可以是 .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>
如您所見,此主題定義了按鈕在基本功能中的外觀/工作方式。 你可以覆蓋它的一部分,但你沒有覆蓋重要的部分(按鈕樣式和類似的)。 因此,如果您自己創建一個新主題並根據自己的喜好設置樣式並設置主題(使用 theme="themename")並且該主題不繼承任何主題,您應該能夠根據自己的喜好設置按鈕樣式而不必擔心關於主題中的默認樣式
基本上:
調用 padding/margin="0dp" 將無濟於事。 主題定義的默認可繪制對象在按鈕可繪制對象中具有此項,這意味着您無法更改它。 所以你要么改變按鈕樣式,要么完全改變主題。 確保主題沒有任何父主題,因為許多主題定義了按鈕樣式。 您不想要主題定義的按鈕樣式。
目前最好的解決方案是使用MaterialButton
代替Button
。
注意:MaterialButton 在視覺上與 Button 和 AppCompatButton 不同。 主要區別之一是 AppCompatButton 在左右兩側有一個 4dp 的內嵌,而 MaterialButton 沒有。 要添加一個 inset 以匹配 AppCompatButton,請將按鈕上的 android:insetLeft 和 android:insetRight 設置為 4dp,或者更改按鈕父布局上的間距。
使用 MaterialButton 替換應用中的按鈕時,您應該檢查這些更改的大小和間距差異。
來源:https ://material.io/develop/android/components/material-button/
我建議你先看看這個以防萬一。
然后,如果不起作用,我建議您使用 android xml drawables 創建自己的樣式(如 azizbekian 建議),並使用 drawable 狀態來區分按下/未按下。
我認為使用您自己的樣式可能是最好的答案,因為它可以進一步讓您更好地控制應用程序的顯示方式,但使用 android 默認主題和樣式還允許用戶擁有自定義樣式,這是一個好主意。 但是,您無法測試每個自定義樣式,因此您無法檢查您的應用程序是否會在所有自定義樣式上正確顯示,因此可能會遇到一些問題。
將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>
在嘗試了很多解決方案之后,我終於得出結論,僅憑標簽我們無法實現這一點。 要刪除按鈕周圍不需要的空間,我的解決方案如下:
<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>
1.添加一個drawable資源文件,命名為button_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作為按鈕背景,大功告成!
我真的不知道我應該稱之為填充還是邊距。
該按鈕正在制定表面高度,以響應觸摸提供視覺反饋。 它是用於表面反應的兩個反饋之一; 第一個是漣漪效應。 例如,凸起按鈕的靜止狀態高度為 2dp,按下狀態高度為 8dp(參見陰影下的凸起按鈕)。 當手指接觸表面時,按鈕會與手指接觸。
我可以知道在按下過程中刪除按鈕填充的最佳方法是什么,同時保留材料設計的按下視覺效果?
回答了第一部分后,如果您希望消除表面高程效果,我不相信您擁有所有的材料設計。
無論如何,這里是如何刪除表面高程視覺反饋:
將動畫文件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"
... />
希望這可以幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.