Answers:
通常,您无法以编程方式更改样式;您可以使用主题或样式来设置屏幕外观,部分布局或XML布局中的单个按钮。但是,可以以编程方式应用主题。
还有一种东西StateListDrawable
,可以让您为自己所处的每种状态定义不同的可绘制对象Button
,无论它们是否处于聚焦状态,选中状态,按下状态,禁用状态等等。
例如,要让按钮在按下时改变颜色,可以定义一个名为res/drawable/my_button.xml
directory 的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"
。
style
属性,但是您可以通过编程方式设置背景的外观,Button
就像其他任何视图一样。另外,作为的Button
继承TextView
,您可以更改文本属性。只要看看这些项目的API文档... developer.android.com/reference/android/view/...
首先,您不需要使用布局填充器来创建简单的Button。您可以使用:
button = new Button(context);
如果要为按钮设置样式,则有两种选择:最简单的一种是只指定代码中的所有元素,就像许多其他答案所建议的那样:
button.setTextColor(Color.RED);
button.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
另一个选择是用XML定义样式,并将其应用于按钮。在一般情况下,您可以ContextThemeWrapper
为此使用a :
ContextThemeWrapper newContext = new ContextThemeWrapper(baseContext, R.style.MyStyle);
button = new Button(newContext);
要更改TextView(或其子类,例如Button)上与文本相关的属性,有一个特殊的方法:
button.setTextAppearance(context, R.style.MyTextStyle);
这最后一个不能用于更改所有属性。例如,要更改填充,您需要使用ContextThemeWrapper
。但对于文本颜色,大小等,您可以使用setTextAppearance
。
是的,您可以在按钮中使用
Button b = new Button(this);
b.setBackgroundResource(R.drawable.selector_test);
您可以像这样进行样式属性:
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"
/>
对于任何寻求“材料”答案的人,请参阅以下SO帖子:Android中带有“材料设计”和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);
}
@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>
在运行时,您知道希望按钮具有哪种样式。因此,预先在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);
其中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);
这就是您可以动态使用样式化按钮的方式。
我使用了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
此示例的样式为:
<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);
我发现这非常有用,因为它可以轻松地重用并保持代码整洁和冗长,我建议仅将此变量用作局部变量,这样,一旦设置完所有样式,我们就可以允许垃圾收集器完成其工作。
我最近遇到了同样的问题。这是我解决的方法。
<?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>
谢谢 !