美文网首页Android新优化
安卓统一样式和主题的一些细节知识点

安卓统一样式和主题的一些细节知识点

作者: 奋斗小青年Jerome | 来源:发表于2017-09-22 13:57 被阅读202次
  • 使用Theme来统一基础背景色
<!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorNormalText</item>
        <item name="windowBackground">@color/windowBackgroundColor</item>
        <item name="textColorPrimary">@color/colorNormalText</item>
    </style>

Theme里面统一设置了默认的背景颜色和字体颜色,在xml布局过程中,不单独对控件设置颜色,则使用默认
Theme的各种参数的解释

theme.png
  1. android:colorPrimaryDark 应用的主要暗色调,statusBarColor默认使用该颜色
  2. android:statusBarColor 状态栏颜色,默认使用colorPrimaryDark
  3. android:colorPrimary 应用的主要色调,actionBar默认使用该颜色
  4. android:windowBackground 窗口背景颜色
  5. android:navigationBarColor 底部栏颜色
  6. android:colorForeground 应用的前景色,ListView的分割线,switch滑动区默认使用该颜色
  7. android:colorBackground 应用的背景色,popMenu的背景默认使用该颜色
  8. android:colorAccent 一般控件的选种效果默认采用该颜色
  9. android:colorControlNormal 控件的默认色调
  10. android:colorControlHighlight 控件按压时的色调
  11. android:colorControlActivated 控件选中时的颜色,默认使用colorAccent
  12. android:colorButtonNormal 默认按钮的背景颜色
  13. android:textColor Button,textView的文字颜色
  14. android:textColorPrimaryDisableOnly RadioButton checkbox等控件的文字
  15. android:textColorPrimary 应用的主要文字颜色,actionBar的标题文字默认使用该颜色
  • 使用Style来统一常用的基础样式
    常用的基础控件(Button,EditTextView)等可以抽取到Style,使用时引用即可,这样要改的时候直接改一个地方即可
  • ToolBar不一定好用
    官方的toolBar在某些情况下不一定好用,比如Title文字不能居中;不能添加左边的menu,左侧的返回按钮navigationIcon不能设置大小和padding值;menu在长按之后会弹出吐司,即使menu的title设置为空字符串,当然这些问题也可以有很多方法弥补,在你确定一定要用toolBar的情况下;否则按照自定义一个跟toolbar高度一样的view的方式来作为toolBar是比较好的选择
  • 设置状态栏的颜色和状态栏字体颜色
    1.安卓4.4以上版本才开始支持修改状态栏颜色
    2.小米的MIUI,魅族的Flyme以及安卓6.0以上版本支持更改状态栏字体颜色,其他版本国内的rom目前没有找到好的解决办法
//小米
  if (window != null) {
            Class clazz = window.getClass();
            try {
                int darkModeFlag = 0;
                Class layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
                Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
                darkModeFlag = field.getInt(layoutParams);
                Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
                if (dark) {
                    extraFlagField.invoke(window, darkModeFlag, darkModeFlag);//状态栏透明且黑色字体
                } else {
                    extraFlagField.invoke(window, 0, darkModeFlag);//清除黑色字体
                }
            
            } catch (Exception e) {

            }
//魅族
 try {
                WindowManager.LayoutParams lp = window.getAttributes();
                Field darkFlag = WindowManager.LayoutParams.class
                        .getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
                Field meizuFlags = WindowManager.LayoutParams.class
                        .getDeclaredField("meizuFlags");
                darkFlag.setAccessible(true);
                meizuFlags.setAccessible(true);
                int bit = darkFlag.getInt(null);
                int value = meizuFlags.getInt(lp);
                if (dark) {
                    value |= bit;
                } else {
                    value &= ~bit;
                }
                meizuFlags.setInt(lp, value);
                window.setAttributes(lp);
                result = true;
            } catch (Exception e) {

            }
//android6.0以上版本
getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);

注意6.0以上版本这里有坑,View的几个状态
1.View.SYSTEM_UI_FLAG_VISIBLE:显示状态栏,
Activity不全屏显示(恢复到有状态的正常情况)。
2.View.INVISIBLE:隐藏状态栏,同时Activity会伸展全屏显示。
3.View.SYSTEM_UI_FLAG_FULLSCREEN:Activity全屏显示,且状态栏被隐藏覆盖掉。
4.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN:Activity全屏显示,但状态栏不会被隐藏覆盖,状态栏依然可见,Activity顶端布局部分会被状态遮住。
5.View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION:效果同 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
6.View.SYSTEM_UI_LAYOUT_FLAGS:效果同View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
7.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION:隐藏虚拟按键(导航栏)。有些手机会用虚拟按键来代替物理按键。
8.View.SYSTEM_UI_FLAG_LOW_PROFILE:状态栏显示处于低能显示状态(low profile模式),状态栏上一些图标显示会被隐藏。

  • 使用着色器实现Drawable的tint功能
    Drawable的setColorFilter滤镜功能能够实现针对drawable的单独着色,例如app的一些icon,在某些情况下需要改变icon的颜色,一般我们就放两张图片,那么使用着色器就只需要一张图片;还有就是某些图片icon的按钮的按压效果,当按下去之后需要设置透明通道,将之前的图片覆盖一下,也可以使用着色器实现
        drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
        iv.setImageDrawable(drawable);

这里有坑,在项目中使用时,发现同一个drawable下的图片,只要设置过一次颜色之后,其他图片都会成为这个颜色,再次设置无效,google了一番,发现是因为Android底层可能为了节约资源,将这个图片在内存中以共享的方式提供,加上这句代码,就可以实现图片在内存中是以copy形式存在(其实copy这个词也不确切,应该是重新引用了)

        drawable.mutate();
        drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
        iv.setImageDrawable(drawable);
  • 使用系统自带的AlertDialog来实现弹窗
    Support V7包在22.1.0之前的任何一个版本,AlertDialog一直都是Android4.0风格,直到Support-V7:22.1.0,在这之前,如果我们的项目中要使用Material样式的Dialog,Android5.0以下的设备根本不支持
    但是,support-v7更新到22.1.0之后,我们就再也不需要使用上面的开源库来获得MaterialDiaolg了
    但是... 系统自带的dialog能够定义的东西非常少,至少在api上没用能够定义字体颜色,按钮字体颜色和大小等属性,导致我们不得不自定义或者用第三方的库,那么其实我们只需要小小的更改一下系统dialog的style,就能实现很多东西
    这里要感谢于神的这篇文章,通过查看分析源码,来自定义style
    我们通过AlertDialog的Builder,跟源码
   static int resolveDialogTheme(@NonNull Context context, @StyleRes int resid) {
        if (resid >= 0x01000000) {   // start of real resource IDs.
            return resid;
        } else {
            TypedValue outValue = new TypedValue();
            context.getTheme().resolveAttribute(R.attr.alertDialogTheme, outValue, true);
            return outValue.resourceId;
        }
    }

发现系统要求我们如果需要自定义dialog属性,需要在theme里面使用alertDialogTheme,那么怎么去写这个alertDialogTheme呢,来看看系统怎么写的,我们就怎么写,于是就按照如下的style来写,这里有个小坑就是,我们自定义完了按钮字体颜色,运行发现content的字体颜色也跟着变了,

 <!--更改的系统的dialog样式-->
    <style name="Theme.AppCompat.Light.Dialog.Alert.Custom" parent="@style/Theme.AppCompat.Light.Dialog.Alert">
        <item name="android:background">@color/dialog_bg_color</item>
        <!--取消按钮字体颜色-->
        <item name="buttonBarNegativeButtonStyle">@style/buttonBarNegative</item>
        <!--确认按钮字体颜色-->
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <style name="buttonBarNegative" parent="@style/Widget.AppCompat.Button.ButtonBar.AlertDialog">
        <item name="android:textColor">@color/title_color</item>
    </style>

查看了一下,忘记加textColorPrimary这个属性
最终如下:

 <!--更改的系统的dialog样式-->
    <style name="Theme.AppCompat.Light.Dialog.Alert.Custom" parent="@style/Theme.AppCompat.Light.Dialog.Alert">
        <item name="android:background">@color/dialog_bg_color</item>
        <!--字体统一颜色-->
        <item name="android:textColorPrimary">@color/title_color</item>
        <!--取消按钮字体颜色-->
        <item name="buttonBarNegativeButtonStyle">@style/buttonBarNegative</item>
        <!--确认按钮字体颜色-->
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <style name="buttonBarNegative" parent="@style/Widget.AppCompat.Button.ButtonBar.AlertDialog">
        <item name="android:textColor">@color/title_color</item>
    </style>
image.png

成功通过更改系统的style实现的MaterialDesign风格的弹窗

相关文章

  • 安卓统一样式和主题的一些细节知识点

    使用Theme来统一基础背景色 Theme里面统一设置了默认的背景颜色和字体颜色,在xml布局过程中,不单独对控件...

  • 样式(style)和主题(theme)资源

    在安卓中,提供了用于对安卓应用进行美化的样式和主题资源,使用这种资源可以开发出各种风格的安卓应用。 样式资源 st...

  • DES 算法

    为了和安卓统一结果,下面附上安卓代码。

  • Toolbar

    ActionBar Android 3.0之后,Google引入了ActionBar,想统一安卓应用的导航栏样式。...

  • Android Toolbar,你想知道的都在这里了

    Android 3.0之后,Google引入了ActionBar,想统一安卓应用的导航栏样式。但由于ActionB...

  • MaterialDesign--(6)Toolbar的使用及其源

    简介 Android 3.0之后,Google引入了ActionBar,想统一安卓应用的导航栏样式。但由于Acti...

  • toolbar总结及简单封装

    Android3.0之后,Google引入了ActionBar,想统一安卓应用的导航栏样式。但由于ActionBa...

  • 什么是ToolBar?

    一、简介 Android3.0之后,Google引入了ActionBar,想要统一安卓应用的导航栏样式。但是由于A...

  • 工作总结

    完成了 书院:共读页的制作与布局修改。读书流程的修复完善与一些样式变动。 Ios内嵌的配音首页作业报告与安卓作统一...

  • jsbridge源码解析 20181118

    jsbridge和安卓提供的@javascript最大的优势在于:(以下“客户端”代表安卓原生页面) 1.格式统一...

网友评论

    本文标题:安卓统一样式和主题的一些细节知识点

    本文链接:https://www.haomeiwen.com/subject/dedtextx.html