如何获得中性按钮的标准颜色



我正在使用带有style=的按钮"?android:attr/buttonBarNeutralButtonStyle

<Button
style="?android:attr/buttonBarNeutralButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Sign in" />

我想获取它的颜色,所以我也可以将其与其他视图元素一起使用。

目前我正在像这样读取它的颜色值:

int color;
View button = findViewById(R.id.passwordSigninButton);
if ((button != null) && (button instanceof Button))
color = ((Button) button).getCurrentTextColor();
// -16738680

。它工作正常。但是我更愿意直接获取与适用样式关联的颜色,而无需使用实际按钮,以防我想在我的布局中没有按钮的情况下使用它。

所以我尝试了这种方法:

TypedValue typedValue = new TypedValue();
getApplicationContext().getTheme().resolveAttribute(
android.R.attr.buttonBarNeutralButtonStyle, typedValue, true);
TypedArray typedArray = context.obtainStyledAttributes(
typedValue.data, new int[]{android.R.attr.textColor});
int color = typedArray.getColor(0, -1);
// -1
typedArray.recycle();

但是我越来越-1,这意味着我没有得到我期望的颜色。

如何从android.R.attr.buttonBarNeutralButtonStyle样式中获得颜色?

请参阅下面的直接派生更新。

您确定中性按钮文本颜色的方法试图复制 Android 在确定颜色时所采取的步骤。这种处理是在引擎盖下的,并且可以从一个版本到另一个版本发生变化,我认为我们从对这个问题的回答中看到了这一点。我相信只要结果相同,Android开发人员就可以随意更改底层实现,因此,即使您可以获得今天有效的解决方案,它也会很脆弱,明天可能会崩溃。

您确实有一个解决方案,但它涉及创建您想要避免的布局。我建议以下方法,我相信这种方法将满足您的目的,会更健壮一些,并且会避免对布局文件的需求。您指示您正在使用创建AppCompatButton按钮的android.support.v7.app.AppCompatDialog

以下两行将为您提供中性按钮文本的颜色,而无需布局或提取属性的复杂性。我已经在运行 API 22 的模拟器和运行 API 7 的三星 S7 上运行 API 24 对此进行了测试,这两个结果都与显式布局一致。

android.support.v7.widget.AppCompatButton button =
new android.support.v7.widget.AppCompatButton(this, null,
android.R.attr.buttonBarNeutralButtonStyle);
int color = button.getCurrentTextColor();

直接派生

虽然我相信上面的解决方案是最好的,但下面的代码将派生所有 API 的中性按钮的默认颜色。此方法仅查找textColor属性,如果未定义,则查找textAppearance并查看其中定义的textColor。看起来不同 API 之间的区别在于指定颜色的方式。此解决方案可能足够强大,可以承受后续更新,但需要注意

主活动.java

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
android.support.v7.widget.AppCompatButton button =
new android.support.v7.widget.AppCompatButton(this, null, android.R.attr.buttonBarNeutralButtonStyle);
Log.d("MainActivity", String.format("<<<< Button color = 0x%08X", button.getCurrentTextColor()));
Log.d("MainActivity", String.format("<<<< Derived color = 0x%08X", getNeutralButtonColor(Color.WHITE)));
}
private int getNeutralButtonColor(int defaultColor) {
TypedArray ta;
int color = defaultColor;
boolean colorFound = false;
int textColorResId;
final int baseAttr = R.attr.buttonBarNeutralButtonStyle;
// Look for an explicit textColor attribute and use it if it is defined.
ta = getTheme().obtainStyledAttributes(null, new int[]{android.R.attr.textColor}, baseAttr, 0);
textColorResId = ta.getResourceId(0, -1);
if (textColorResId == -1) { // try to get color if not resource id
int type = ta.getType(0);
if (type >= TypedValue.TYPE_FIRST_COLOR_INT && type <= TypedValue.TYPE_LAST_COLOR_INT) {
color = ta.getColor(0, defaultColor);
colorFound = true;
}
}
ta.recycle();
if (textColorResId == -1 && !colorFound) {
// No color, yet. See if textAppearance is defined.
ta = obtainStyledAttributes(null, new int[]{android.R.attr.textAppearance},
baseAttr, 0);
int textAppearanceId = ta.getResourceId(0, -1);
if (textAppearanceId != -1) {
// OK, textAppearance is defined. Get the embedded textColor.
ta.recycle();
ta = obtainStyledAttributes(textAppearanceId, new int[]{android.R.attr.textColor});
textColorResId = ta.getResourceId(0, -1);
if (textColorResId == -1) { // try to get color if not resource id
int type = ta.getType(0);
if (type >= TypedValue.TYPE_FIRST_COLOR_INT && type <= TypedValue.TYPE_LAST_COLOR_INT) {
color = ta.getColor(0, defaultColor);
colorFound = true;
}
}
}
ta.recycle();
}
if (textColorResId != -1 && !colorFound) {
ColorStateList colorStateList = AppCompatResources.getColorStateList(this, textColorResId);
if (colorStateList != null) {
color = colorStateList.getDefaultColor();
colorFound = true; // in case needed later
}
}
return color;
}
@SuppressWarnings("unused")
private static final String TAG = "MainActivity";
}

您可以在项目的 values 文件夹中创建颜色.xml并定义要用于视图的颜色。 例如:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="white">#FFFFFF</color>
<color name="green">#008000</color>
<color name="blue">#0000FF</color>
<color name="black">#000000</color>
</resources>

然后在您的样式中,参考此文件中的颜色:

例如:

<style name="ButtonColor" parent="@android:style/Widget.Button">
<item name="android:textColor">@color/blue</item>
</style> 

然后,对于您想要的任何其他元素,您不需要依赖于视图,只需从该颜色访问即可.xml

textView.setTextColor(getResources().getColor(R.color.blue));

但是如果你想真正从样式中访问它:

// The attributes you want retrieved
int[] attrs = {android.R.attr.textColor, android.R.attr.text};
// Parse style
TypedArray typedArray  = obtainStyledAttributes(R.style.stylename, attrs);
// Get color from style
int textColor = typedArray.getColor(0, "default color");
//Check by priting
Log("Retrieved textColor as hex:", Integer.toHexString(textColor));
//recycle
typedArray.recycle()

我运行了您上面给出的相同代码。我能够得到一个整数值。

输出:系统输出:打印颜色 int 值:-49023

import android.content.res.TypedArray;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.TypedValue;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TypedValue typedValue = new TypedValue();
getApplicationContext().getTheme().resolveAttribute(
android.R.attr.buttonBarNeutralButtonStyle, typedValue, true);
TypedArray typedArray = this.obtainStyledAttributes(
typedValue.data, new int[]{android.R.attr.textColor});
int color = typedArray.getColor(0, -1);
System.out.println("Printing the color int value: " + color);
typedArray.recycle();
}
}

下面的代码有不同的风格:

getApplicationContext().getTheme().resolveAttribute(
android.R.attr.actionButtonStyle, typedValue, true);
TypedArray typedArray = this.obtainStyledAttributes(
typedValue.data, new int[]{android.R.attr.colorForeground});
int color = typedArray.getColor(0, -1);
System.out.println("Printing the color int value: " + color);

输出:系统输出:打印颜色整数值:-16777216


我正在使用安卓工作室 3.0.1 版本 #AI-171.4443003,构建于 2017 年 11 月 9 日 JRE:1.8.0_152-release-915-b08 x86_64 JVM: OpenJDK 64-bit Server VM by JetBrains s.r.o Mac OS X 10.13.3

最新更新