Android新优化

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

2017-09-22  本文已影响202人  奋斗小青年Jerome
<!-- 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的标题文字默认使用该颜色
//小米
  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.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);
   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风格的弹窗

上一篇下一篇

猜你喜欢

热点阅读