寻找如何在 Android 上更改小部件的样式一直很麻烦。例如,DatePickerDialog 具有不同的 Holo 和 Material 设计风格。因此,对话框的样式可能取决于 SDK 值或您是否使用 AppCompat 库。文档也很少。
如果像Hierarchy Viewer 这样的工具能够显示小部件的属性和当前主题,那就太好了。但是,我还没有遇到过这样的工具。
我们可以在视图创建后获取当前的主题和属性。以下是我在DatePickerDialog 上编写和测试的几种方法来查找正在使用的样式:
从上下文中获取当前主题:
static String getThemeNameFromContext(Context context) {
Resources.Theme theme = context.getTheme();
String themeName;
try {
Field field = theme.getClass().getDeclaredField("mThemeResId");
if (!field.isAccessible()) {
field.setAccessible(true);
}
int themeResId = field.getInt(theme);
themeName = context.getResources().getResourceEntryName(themeResId);
} catch (Exception e) {
// If we are here then the context is most likely the application context.
// The theme for an application context is always "Theme.DeviceDefault"
themeName = "Theme.DeviceDefault";
}
return themeName;
}
获取属性的名称/值:
static String getResourceName(Context context, int attribute) {
TypedArray typedArray = context.obtainStyledAttributes(new int[]{attribute});
try {
int resourceId = typedArray.getResourceId(0, 0);
return context.getResources().getResourceEntryName(resourceId);
} finally {
typedArray.recycle();
}
}
在下面的示例中,我创建了一个DatePickerDialog,并使用上述方法获得了对话框使用的主题和属性值以及对话框的正按钮:
// Create the DatePickerDialog
DatePickerDialog datePickerDialog = new DatePickerDialog(getActivity(),
new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
}
}, 2015, Calendar.SEPTEMBER, 9);
// Show the dialog
datePickerDialog.show();
// Get the positive button from the dialog:
Button positiveButton = datePickerDialog.getButton(DatePickerDialog.BUTTON_POSITIVE);
// Get the theme used by this dialog
String theme = getThemeNameFromContext(datePickerDialog.getContext());
// Get the date picker style used by the dialog
String datePickerStyle = getResourceName(datePickerDialog.getContext(), android.R.attr.datePickerStyle);
// Get the style of the positive button:
String buttonStyle = getResourceName(positiveButton.getContext(), android.R.attr.buttonStyle);
Log.i("LOGTAG", "Theme: " + theme);
Log.i("LOGTAG", "datePickerStyle: " + positiveButton);
Log.i("LOGTAG", "buttonStyle: " + buttonStyle);
在我的测试项目中,我得到了 theme、datePickerStyle 和 buttonStyle 的这些值:
主题:ThemeOverlay.Material.Dialog
datePickerStyle: Widget.Material.Light.DatePicker
buttonStyle: Widget.Material.Light.Button
这有点帮助,但我们仍然没有改变正面和负面的按钮样式。如果我们查看source for DatePickerDialog,我们可以看到它扩展了AlertDialog。这使事情变得更加困难,因为您需要在主题中设置自定义样式,这将影响所有 AlertDialog 按钮。如果您需要有关如何更改 buttonStyle 的示例,请发表评论。
更好的方法是在对话框可见后设置正面和负面按钮的样式。例如,在您的DialogFragment 中,您可以在onStart() 中放置以下代码来设置按钮样式:
@Override
public void onStart() {
super.onStart();
DatePickerDialog dialog = (DatePickerDialog) getDialog();
Button btnPos = dialog.getButton(DatePickerDialog.BUTTON_POSITIVE);
Button btnNeg = dialog.getButton(DatePickerDialog.BUTTON_NEGATIVE);
/* customize the buttons here */
btnPos.setText("CUSTOM");
btnPos.setTextAppearance(android.R.style.TextAppearance_Large);
btnNeg.setTextColor(Color.RED);
}
结论:
您可以在其他视图上使用上述方法来查找适用于该视图的样式。在 Android 上为小部件设置样式仍然是一个痛苦。您可能需要不时深入研究源代码和 XML。