ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

android – 有没有一种通用的方法来查找适用于View的样式?

2019-05-19 19:14:11  阅读:166  来源: 互联网

标签:android android-styles


一般来说,为了改变任何UI元素的外观,您是如何找到要覆盖的主题属性的?

目前,我依赖于遍历框架源文件:values.xml中的主题定义(通常是支持库变体),attrs.xml中的属性定义以及R.styleable类文档.

但这完全是命中注定.这不仅耗费时间,而且有时我会完全错过,例如我一直在努力寻找如何在DatePickerDialog的OK和Cancel按钮中更改文本样式.您可以随意使用它作为示例,但如果您这样做,请概述您的发现过程.我正在寻找的答案是如何发现任何UI元素的应用样式,

还是没有确定的方法可以找到答案?你只需要知道吗?

解决方法:

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,datePickerStylebuttonStyle的这些值:

Theme: 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);
}

enter image description here

结论:

您可以在其他视图上使用上述方法来查找适用于该视图的样式. Android上的a **样式小部件仍然很痛苦.您可能需要不时地浏览源代码和XML.

标签:android,android-styles
来源: https://codeday.me/bug/20190519/1136781.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有