我正在尝试以编程方式创建一些按钮以将它们添加到现有的ViewGroup。这样可以正常工作,但我无法使用正确的样式初始化按钮。
我知道,一旦创建了视图,就无法设置/更改。但到目前为止我发现的所有解决方案都说,创建具有自定义样式的视图应该没问题(从我认为的API级别11开始,我使用的是14 +):
Button button = new Button (getActivity(), null, R.style.MyButtonStyle);
唯一的效果是,按钮创建时没有任何样式。没有背景,所以选择器,没有边距/填充只是纯文本。我认为MyButtonStyle会被破坏,但是使用MyButtonStyle在XML中创建按钮没问题。
为什么这不起作用?
答案 0 :(得分:7)
我终于找到了解决方案!问题是,为什么以下不起作用:
Button button = new Button (getActivity(), null, R.style.MyButtonStyle);
原来,问题是,正在使用 R.style.xxx
而不是 R.attr.xxx
。在View(Context context, AttributeSet attrs, int defStyleAttr)
的实现中或者至少在这个contstructor的文档中,这似乎是bug:第三个参数必须是R.attr才能使构造函数正常工作并正确应用样式。
因此,为了使构造函数正常工作,必须向/res/values/attr.xml
和/res/values/styles.xml
添加更多代码:
<!-- /res/values/attr.xml -->
<declare-styleable name="AppTheme">
<attr name="specialButtonStyle" format="reference"/>
</declare-styleable>
<!-- /res/values/styles.xml -->
<style name="AppTheme" parent="AppBaseTheme">
...
<item name="specialButtonStyle">@style/MyButtonStyle</item>
</style>
<style name="MyButtonStyle" parent="@android:style/Widget.Button">
...
</style>
// In Java we can now use R.attr.specialButtonStyle instead of R.style.MyButtonStyle
// getActivity() is used because I am working in a Fragment. Within an
// Activity this can be used instead...
Button button = new Button(getActivity(), null, R.attr.specialButtonStyle);
令人讨厌的是,文档尚未针对此问题进行更新。有关此问题的第一个错误报告已于2011年提交......
还需要编写一些额外的代码来运行此解决方案要快得多(从我的角度来看)比通常提出的扩展XML布局要好得多。
答案 1 :(得分:0)
答案 2 :(得分:0)
你可以这样做。
首先在具有自定义样式的项目的res/drawable
文件夹中创建一个xml文件。 (比如buttonstyle.xml)。然后,
Button btn = new Button(this);
btn.setText("Test Example");
btn.setId(R.string.btn_name);
btn.setBackground(R.drawable.buttonstyle);
希望这会对你有所帮助。
答案 3 :(得分:0)
我不确定它为什么不起作用。但是想分享我的答案,这有助于我有自定义样式按钮。
在您的活动中,包括以下内容:
Button btnMyCustomButton = (Button) findViewById(R.id.myTestButton);
在布局xml文件中,包括以下内容:
<Button
android:id="@+id/myTestButton"
android:background="@drawable/my_custom_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center|bottom"
android:layout_marginBottom="30dp"
style="@style/my_custom_button_text"/>
在drawable文件夹中,创建my_custom_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>
<solid
android:color="#35adad" />
<stroke
android:width="1dp"
android:color="#2f9999" />
<corners
android:radius="6dp" />
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
</item>
<item>
<shape>
<gradient
android:startColor="#35adad"
android:endColor="#2f9999"
android:angle="270" />
<stroke
android:width="1dp"
android:color="#2f9999" />
<corners
android:radius="6dp" />
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
</item>
</selector>
您还可以在style.xml中包含以下内容,以便按钮文本也可以自定义。
<style name="my_custom_button_text" >
<item name="android:layout_width" >fill_parent</item>
<item name="android:layout_height" >wrap_content</item>
<item name="android:textColor" >#ffffff</item>
<item name="android:gravity" >center</item>
<item name="android:layout_margin" >3dp</item>
<item name="android:textSize" >30sp</item>
<item name="android:textStyle" >bold</item>
<item name="android:shadowColor" >#000000</item>
<item name="android:shadowDx" >1</item>
<item name="android:shadowDy" >1</item>
<item name="android:shadowRadius" >2</item>
</style>
答案 4 :(得分:0)
您可以使用ContextThemeWrapper
来实现这一目标ContextThemeWrapper ctw = new ContextThemeWrapper(this, R.style.MyButtonStyle);
Button = new Button(ctw);
修改强>
我刚检查了源代码以及您的代码(我猜我的代码)不起作用的原因现在已经很清楚了。
public View(Context context, AttributeSet attrs, int defStyleAttr) {
this(context);
TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.View,
defStyleAttr, 0);
attrs
为空,TypedArray
没有任何值可供使用。
我以前使用的代码用于Dialogs,我认为它的工作原理相同。
您可以在View source code上查看。
因此,如果您在构造函数上传递AttributeSet
,那么可能有效的更新答案。我不知道该怎么做,但是查看文档(HERE)你可能会做那样的事情:
// the docs says `myResource` so probably the style ID
XmlPullParser parser = resources.getXml(R.style.MyButtonStyle);
AttributeSet attributes = Xml.asAttributeSet(parser);
Button button = new Button (getActivity(), attributes, R.style.MyButtonStyle);