如何以自定义样式以编程方式创建/初始化Button?

时间:2014-06-17 11:21:46

标签: android button user-interface styles

我正在尝试以编程方式创建一些按钮以将它们添加到现有的ViewGroup。这样可以正常工作,但我无法使用正确的样式初始化按钮。

我知道,一旦创建了视图,就无法设置/更改。但到目前为止我发现的所有解决方案都说,创建具有自定义样式的视图应该没问题(从我认为的API级别11开始,我使用的是14 +):

Button button = new Button (getActivity(), null, R.style.MyButtonStyle);

唯一的效果是,按钮创建时没有任何样式。没有背景,所以选择器,没有边距/填充只是纯文本。我认为MyButtonStyle会被破坏,但是使用MyButtonStyle在XML中创建按钮没问题。

为什么这不起作用?

5 个答案:

答案 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)

请尝试使用此链接:
__1__
__2__
__3__

答案 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);