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

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

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

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

259971 次浏览

通常,您不能以编程方式更改样式; 您可以使用 主题或风格在 XML 布局中设置屏幕的外观、布局的一部分或单个按钮。然而,主题可以是 以编程方式应用

还有一个类似于 StateListDrawable的东西,它允许您为您的 Button可能处于的每个状态定义不同的绘图,无论是聚焦的、选择的、按下的、禁用的等等。

例如,要让按钮在按下时改变颜色,可以定义一个名为 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>

You can then apply this selector to a Button by setting the property android:background="@drawable/my_button".

是的,您可以在按钮中使用

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

The answer by @Dayerman and @h_rules is right. 为了给出一个详细的代码示例, 在可绘制的文件夹中,创建一个名为 button _ ability. 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>

然后在爪哇,

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

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

[ color 在 color.xml 中定义为:

<resources>


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


</resources>

First of all, you don't need to use a layout inflater to create a simple Button. You can just use:

button = new Button(context);

If you want to style the button you have 2 choices: the simplest one is to just specify all the elements in code, like many of the other answers suggest:

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

The other option is to define the style in XML, and apply it to the button. In the general case, you can use a ContextThemeWrapper for this:

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

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

button.setTextAppearance(R.style.MyTextStyle);

或者,如果你需要支持 API-23之前的设备(Android 6.0)

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

此方法不能用于更改所有属性; 例如,要更改填充,需要使用 ContextThemeWrapper。但是对于文本颜色,大小等,你可以使用 setTextAppearance

在运行时,您知道希望按钮具有什么样式。因此,事先,在布局文件夹的 xml 中,您可以准备好所需样式的按钮。因此,在布局文件夹中,您可能有一个名为: 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);

其中容器是创建片段时重写的 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);

And that's how you can dynamically work with stylized buttons.

For anyone looking for a Material answer see this SO post: 材质设计和 AppCompat 在 Android 中的着色按钮

我使用这个答案的组合将按钮的默认文本颜色设置为白色: 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 can be just a regular Button or a AppCompat button if you wish - I tested the above code with both types of buttons and it works.

编辑: 我发现前棒棒糖设备不与上述代码工作。看看这篇关于如何添加对前棒棒糖设备的支持的文章: 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);
}

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

<?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>
  • 我对 android 使用了一个 LinearLayout: weightSum = “2”
  • 我给了两个子元素 android: lay _ weight = “1” (我给每个父空间的50% (宽度和高度))
  • 最后,我给两个子元素不同的背景颜色,以有最终的效果。

谢谢!

如果您正在使用 Support 库,您可以简单地使用

TextViewCompat.setTextAppearance(textView, R.style.AppTheme_TextStyle_ButtonDefault_Whatever);

其他视图也有类似的类: -)

你可以这样做样式属性:

Button myButton = new Button(this, null,android.R.attr.buttonBarButtonStyle);

取代:

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn"
style="?android:attr/buttonBarButtonStyle"


/>

我使用 holder 模式为此创建了一个助手界面。

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中声明一个 stylable,这个例子的 stylable 是:

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

我发现这非常有帮助,因为它可以很容易地重用,并保持代码的干净和冗长,我建议使用这只作为一个本地变量,这样我们就可以让垃圾收集器做它的工作,一旦我们完成设置所有的样式。

根据您希望更改的样式属性,您可以使用巴黎图书馆:

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

支持背景、填充、 textSize、 textColor 等许多属性。

免责声明: 图书馆的作者是我。