我正在尝试在整个应用程序中应用自定义Button背景,但只有在我以编程方式执行时才会起作用。
这是 styles.xml 。我使用<item name="android:buttonStyle">@style/OverlayButton</item>
来表示自定义样式“OverlayButton”(顺便说一下,<item name="buttonStyle">@style/OverlayButton</item>
给出“找不到与给定名称匹配的资源:attr'buttonStyle'。”)然后<item name="android:background">@drawable/overlay_button</item>
调用自定义Drawable
。
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<!--
Base application theme, dependent on API level. This theme is replaced
by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Light">
<!--
Theme customizations available in newer API levels can go in
res/values-vXX/styles.xml, while customizations related to
backward-compatibility can go here.
-->
</style>
<!-- Application theme -->
<style name="AppTheme" parent="AppBaseTheme">
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
<!-- http://stackoverflow.com/questions/6159113/android-where-is-the-spinner-widgets-text-color-attribute-hiding -->
<item name="android:spinnerItemStyle">@style/SpinnerItem</item>
<item name="android:spinnerDropDownItemStyle">@style/SpinnerItem.DropDownItem</item>
<!-- http://stackoverflow.com/questions/8922924/how-to-change-android-spinner-popupbackground -->
<!-- http://www.ezzylearning.com/tutorial.aspx?tid=1763429 -->
<item name="android:listViewStyle">@style/myListView</item>
<item name="android:buttonStyle">@style/OverlayButton</item>
</style>
<style name="SpinnerItem" parent="@android:style/Widget.TextView.SpinnerItem">
<item name="android:textColor">#ADD8E6</item>
</style>
<style name="SpinnerItem.DropDownItem" parent="@android:style/Widget.DropDownItem.Spinner">
<item name="android:textColor">#ADD8E6</item>
</style>
<style name="myListView" parent="@android:style/Widget.ListView">
<item name="android:background">@drawable/intro_spinner</item>
</style>
<!-- Style for Overlay Buttons -->
<style name="OverlayButton" parent="@android:style/Widget.Button">
<item name="android:background">@drawable/overlay_button</item>
<item name="android:gravity">center_vertical|center_horizontal</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textSize">12sp</item>
<item name="android:textColor">#FF000000</item>
<item name="android:layout_marginLeft">0dp</item>
<item name="android:layout_marginRight">0dp</item>
<item name="android:layout_marginTop">10dp</item>
<item name="android:layout_marginBottom">10dp</item>
</style>
<!-- Style for Confirmation Dialog -->
<style name="AlertDialogCustom" parent="@android:style/Theme.Dialog">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:background">@drawable/dialog_background</item>
<item name="android:textColor">#FF000000</item>
<item name="android:textSize">12sp</item>
<item name="android:typeface">monospace</item>
</style>
</resources>
自定义Drawable, overlay_button.xml 就在这里。
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" >
<shape>
<gradient
android:startColor="#999999"
android:endColor="#c0c0c0"
android:angle="270" />
<stroke
android:width="3dp"
android:color="#202619" />
<corners
android:radius="3dp" />
<padding
android:left="1dp"
android:top="1dp"
android:right="1dp"
android:bottom="1dp" />
<margin
android:left="5dp"
android:top="5dp"
android:right="5dp"
android:bottom="5dp" />
</shape>
</item>
<item android:state_focused="true" >
<shape>
<gradient
android:endColor="#999999"
android:startColor="#c0c0c0"
android:angle="270" />
<stroke
android:width="3dp"
android:color="#202619" />
<corners
android:radius="3dp" />
<padding
android:left="1dp"
android:top="1dp"
android:right="1dp"
android:bottom="1dp" />
<margin
android:left="5dp"
android:top="5dp"
android:right="5dp"
android:bottom="5dp" />
</shape>
</item>
<item>
<shape>
<gradient
android:endColor="#aa393939"
android:startColor="#aa737373"
android:angle="270" />
<stroke
android:width="3dp"
android:color="#202619" />
<corners
android:radius="3dp" />
<padding
android:left="1dp"
android:top="1dp"
android:right="1dp"
android:bottom="1dp" />
<margin
android:left="5dp"
android:top="5dp"
android:right="5dp"
android:bottom="5dp" />
</shape>
</item>
</selector>
当我使用final Button b = new Button(context);
创建一个按钮时,我没有获得自定义Drawable。然而,这有效:
final Button b = new Button(context);
Drawable buttonStates; // get Drawable to set button states
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
buttonStates = context.getResources().getDrawable(R.drawable.overlay_button, context.getTheme());
} else {
buttonStates = context.getResources().getDrawable(R.drawable.overlay_button);
}
b.setBackground(buttonStates);
为什么这应该以编程方式工作,而不是在XML中工作?
更新:@ r-zagórski有一个很好的线索。 XML膨胀按钮采用自定义样式并按预期工作。无法工作的按钮以编程方式创建,并通过LinearLayout.addView(b)
插入。 (顺便说一句,final Button b = new Button(context, null, R.drawable.overlay_button_selector)
不起作用。)我不明白为什么这不像XML夸大的按钮那样工作。
答案 0 :(得分:0)
不幸的是,这不是应该如何定义适当的有状态背景。 一种正确的方法是为每个状态定义一个drawable并使用&#34; selector&#34;来绑定它们。
在您的情况下,在res/drawable
文件夹中定义3个文件:
overlay_button
:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient
android:endColor="#aa393939"
android:startColor="#aa737373"
android:angle="270" />
<stroke
android:width="3dp"
android:color="#202619" />
<corners
android:radius="3dp" />
<padding
android:left="1dp"
android:top="1dp"
android:right="1dp"
android:bottom="1dp" />
<margin
android:left="5dp"
android:top="5dp"
android:right="5dp"
android:bottom="5dp" />
</shape>
</item>
</layer-list>
overlay_button_focused
:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient
android:endColor="#999999"
android:startColor="#c0c0c0"
android:angle="270" />
<stroke
android:width="3dp"
android:color="#202619" />
<corners
android:radius="3dp" />
<padding
android:left="1dp"
android:top="1dp"
android:right="1dp"
android:bottom="1dp" />
<margin
android:left="5dp"
android:top="5dp"
android:right="5dp"
android:bottom="5dp" />
</shape>
</item>
</layer-list>
overlay_button_pressed
:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item >
<shape>
<gradient
android:startColor="#999999"
android:endColor="#c0c0c0"
android:angle="270" />
<stroke
android:width="3dp"
android:color="#202619" />
<corners
android:radius="3dp" />
<padding
android:left="1dp"
android:top="1dp"
android:right="1dp"
android:bottom="1dp" />
<margin
android:left="5dp"
android:top="5dp"
android:right="5dp"
android:bottom="5dp" />
</shape>
</item>
</layer-list>
选择器文件 overlay_selector
:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/overlay_button_focused" android:state_focused="true"/>
<item android:drawable="@drawable/overlay_button_pressed" android:state_pressed="true"/>
<item android:drawable="@drawable/overlay_button"/>
</selector>
styles.xml
:
<style name="OverlayButton" parent="@android:style/Widget.Button">
<item name="android:background">@drawable/overlay_selector</item>
....
</style>
如果此选择器不适合您的需要,请创建其他状态。在Android btn_default.xml
文件夹中的Android res/drawable
中查找参考。
进一步参考see this