如何以编程方式在视图中设置样式属性

时间:2010-01-06 21:08:13

标签: android styles

我从XML获得了一个视图,其代码如下:

Button view = (Button) LayoutInflater.from(this).inflate(R.layout.section_button, null);

我想为按钮设置一个“样式”我怎么能在java中这样做,因为想要为我将使用的每个按钮使用几种样式。

10 个答案:

答案 0 :(得分:49)

通常,您无法以编程方式更改样式;您可以使用themes or styles设置XML布局中的屏幕外观或部分布局或单个按钮。但是,主题可以是be applied programmatically

还有一个StateListDrawable这样的东西可以让你为Button所处的每个状态定义不同的drawable,无论是聚焦,选择,按下,禁用等等。

例如,要让按钮在按下时更改颜色,您可以定义一个名为res/drawable/my_button.xml目录的XML文件,如下所示:

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

然后,您可以通过设置属性Button将此选择器应用于android:background="@drawable/my_button"

答案 1 :(得分:40)

首先,您不需要使用布局inflater来创建简单的Button。你可以使用:

button = new Button(context);

如果你想设置按钮的样式,你有两个选择:最简单的就是在代码中指定所有元素,就像许多其他答案所示:

button.setTextColor(Color.RED);
button.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);

另一个选项是在XML中定义样式,并将其应用于按钮。在一般情况下,您可以使用ContextThemeWrapper

ContextThemeWrapper newContext = new ContextThemeWrapper(baseContext, R.style.MyStyle);
button = new Button(newContext);

要更改TextView(或其子类,如Button)上与文本相关的属性,有一种特殊方法:

button.setTextAppearance(context, R.style.MyTextStyle);

最后一个不能用于更改所有属性;例如,要更改填充,您需要使用ContextThemeWrapper。但对于文字颜色,大小等,您可以使用setTextAppearance

答案 2 :(得分:14)

是的,您可以使用例如按钮

Button b = new Button(this);
b.setBackgroundResource(R.drawable.selector_test);

答案 3 :(得分:6)

对于寻找材质答案的任何人,请参阅此SO帖子:Coloring Buttons in Android with Material Design and AppCompat

我使用此答案的组合将按钮的默认文本颜色设置为白色为我的按钮: https://stackoverflow.com/a/32238489/3075340

然后这个回答https://stackoverflow.com/a/34355919/3075340以编程方式设置背景颜色。代码是:

ViewCompat.setBackgroundTintList(your_colored_button,
 ContextCompat.getColorStateList(getContext(),R.color.your_custom_color));
如果你愿意,

your_colored_button可以只是一个普通的Button或一个AppCompat按钮 - 我用两种类型的按钮测试了上面的代码并且它可以工作。

编辑:我发现前棒棒糖设备无法使用上述代码。请参阅此帖子,了解如何添加对棒棒糖前设备的支持:https://stackoverflow.com/a/30277424/3075340

基本上这样做:

Button b = (Button) findViewById(R.id.button);
ColorStateList c = ContextCompat.getColorStateList(mContext, R.color.your_custom_color;
Drawable d = b.getBackground();
if (b instanceof AppCompatButton) {
    // appcompat button replaces tint of its drawable background
    ((AppCompatButton)b).setSupportBackgroundTintList(c);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    // Lollipop button replaces tint of its drawable background
    // however it is not equal to d.setTintList(c)
    b.setBackgroundTintList(c);
} else {
    // this should only happen if 
    // * manually creating a Button instead of AppCompatButton
    // * LayoutInflater did not translate a Button to AppCompatButton
    d = DrawableCompat.wrap(d);
    DrawableCompat.setTintList(d, c);
    b.setBackgroundDrawable(d);
}

答案 4 :(得分:5)

@Dayerman和@h_rules的回答是正确的。 用代码给出一个详细的例子, 在drawable文件夹中,创建一个名为button_disabled.xml

的xml文件
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" android:padding="10dp">   
 <solid android:color="@color/silver"/>
<corners
   android:bottomRightRadius="20dp"
   android:bottomLeftRadius="20dp"
   android:topLeftRadius="20dp"
   android:topRightRadius="20dp"/>
</shape>

然后在Java中,

((Button) findViewById(R.id.my_button)).setEnabled(false);
((Button) findViewById(R.id.my_button)).setBackgroundResource(R.drawable.button_disabled);

这会将按钮的属性设置为禁用,并将颜色设置为银色。

[颜色在color.xml中定义为:

<resources>

    <color name="silver">#C0C0C0</color>

</resources>

答案 5 :(得分:5)

如果您使用的是支持库,则只需使用

即可
TextViewCompat.setTextAppearance(getContext(), R.style.AppTheme_TextStyle_ButtonDefault_Whatever);

用于TextViews和Buttons。其余视图有类似的类: - )

答案 6 :(得分:3)

在运行时,您知道按钮所需的样式。所以事先,在布局文件夹中的xml中,您可以使用所需的样式准备好所有按钮。因此,在layout文件夹中,您可能有一个名为:button_style_1.xml的文件。该文件的内容可能如下所示:

<?xml version="1.0" encoding="utf-8"?>
<Button
    android:id="@+id/styleOneButton"
    style="@style/FirstStyle" />

如果您正在使用片段,那么在onCreateView中,您会膨胀该按钮,例如:

Button firstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false);

其中container是与创建片段时重写的onCreateView方法关联的ViewGroup容器。

还需要两个这样的按钮吗?你可以像这样创建它们:

Button secondFirstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false);
Button thirdFirstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false);

您可以自定义这些按钮:

secondFirstStyleBtn.setText("My Second");
thirdFirstStyleBtn.setText("My Third");

然后将自定义的程式化按钮添加到您在onCreateView方法中也充气的布局容器中:

_stylizedButtonsContainer = (LinearLayout) rootView.findViewById(R.id.stylizedButtonsContainer);

_stylizedButtonsContainer.addView(firstStyleBtn);
_stylizedButtonsContainer.addView(secondFirstStyleBtn);
_stylizedButtonsContainer.addView(thirdFirstStyleBtn);

这就是你如何动态使用程式化按钮。

答案 7 :(得分:3)

根据您想要更改的样式属性,您可以使用Paris库:

Button view = (Button) LayoutInflater.from(this).inflate(R.layout.section_button, null);
Paris.style(view).apply(R.style.YourStyle);

支持许多属性,如background,padding,textSize,textColor等。

免责声明:我撰写了图书馆。

答案 8 :(得分:0)

我使用持有人模式为此创建了一个辅助界面。

public interface StyleHolder<V extends View> {
    void applyStyle(V view);
}

现在,对于您想要实际使用的每个样式,只需实现界面,例如:

public class ButtonStyleHolder implements StyleHolder<Button> {

    private final Drawable background;
    private final ColorStateList textColor;
    private final int textSize;

    public ButtonStyleHolder(Context context) {
        TypedArray ta = context.obtainStyledAttributes(R.style.button, R.styleable.ButtonStyleHolder);

        Resources resources = context.getResources();

        background = ta.getDrawable(ta.getIndex(R.styleable.ButtonStyleHolder_android_background));

        textColor = ta.getColorStateList(ta.getIndex(R.styleable.ButtonStyleHolder_android_textColor));

        textSize = ta.getDimensionPixelSize(
                ta.getIndex(R.styleable.ButtonStyleHolder_android_textSize),
                resources.getDimensionPixelSize(R.dimen.standard_text_size)
        );

        // Don't forget to recycle!
        ta.recycle();
    }

    @Override
    public void applyStyle(Button btn) {
        btn.setBackground(background);
        btn.setTextColor(textColor);
        btn.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
    }
}

attrs.xml中声明一个样式,此示例的样式为:

<declare-styleable name="ButtonStyleHolder">
    <attr name="android:background" />
    <attr name="android:textSize" />
    <attr name="android:textColor" />
</declare-styleable>

以下是styles.xml中声明的样式:

<style name="button">
    <item name="android:background">@drawable/button</item>
    <item name="android:textColor">@color/light_text_color</item>
    <item name="android:textSize">@dimen/standard_text_size</item>
</style>

最后风格持有者的实施:

Button btn = new Button(context);    
StyleHolder<Button> styleHolder = new ButtonStyleHolder(context);
styleHolder.applyStyle(btn);

我发现这非常有用,因为它可以很容易地重用并保持代码干净和冗长,我建议仅将其用作本地变量,以便我们可以让垃圾收集器在我们完成后完成其工作设置所有样式。

答案 9 :(得分:-1)

我最近遇到了同样的问题。这是我如何解决它。

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

    <!-- This is the special two colors background START , after this LinearLayout, you can add all view that have it for main background-->
    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"

    android:weightSum="2"

    android:background="#FFFFFF"
    android:orientation="horizontal"
    >

    <View
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="#0000FF" />

    <View
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="#F000F0" />
    </LinearLayout>
    <!-- This is the special two colors background END-->

   <TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:gravity="center"
    android:text="This Text is centered with a special backgound,
    You can add as much elements as you want as child of this RelativeLayout"
    android:textColor="#FFFFFF"
    android:textSize="20sp" />
</RelativeLayout>
  • 我使用了一个LinearLayout和android:weightSum =&#34; 2&#34;
  • 我给了两个子元素android:layout_weight =&#34; 1&#34; (我给了每个50%的父空间(宽度和高度))
  • 最后,我给了两个子元素不同的背景颜色以产生最终效果。

谢谢!