5

Android 的标题栏和状态栏

 3 years ago
source link: https://segmentfault.com/a/1190000040434927
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Android 的标题栏和状态栏

标题栏和状态栏是每一个Android开发都要去处理的
一:标题栏
你打开任何一个App都有相对应的标题栏,那么Android系统提供给我们的标题栏是什么了
我们Android Studio创建一个应用

<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyTest">//这个Application节点给我们一个默认的主题风格,这样的话整个app的主题风格都是这个,我们也可以设置自己的activity的主题风格
        <activity android:name=".MainActivity"
           android:theme="@style/ss">//这个设置了自己Activity的主题风格
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

我们先看一下默认现在的主题风格是什么

    <style name="Theme.MyTest" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        <!-- Primary brand color. -->
        <item name="colorPrimary">@color/purple_500</item>//您的应用的主要品牌颜色,主要用于主题
        <item name="colorPrimaryVariant">@color/purple_700</item>//您的主要品牌颜色的较浅/较暗变体,在主题中很少使用
        <item name="colorOnPrimary">@color/white</item>//用于显示在原色上方的元素的颜色(例如,文本和图标,根据可访问性,通常为白色或半透明的黑色)
        <!-- Secondary brand color. -->
        <item name="colorSecondary">@color/teal_200</item>//您应用程式的次要品牌色彩,主要用于强调某些需要突出的小部件
        <item name="colorSecondaryVariant">@color/teal_700</item>//您的次要品牌颜色的较浅/较深变体,在主题中很少使用
        <item name="colorOnSecondary">@color/black</item>//用于显示在辅助颜色顶部的元素的颜色
        <!-- Status bar color. -->
        <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>//状态栏使用的颜色
        <!-- Customize your theme here. -->
    </style>

默认的父类的主题风格是parent="Theme.MaterialComponents.DayNight.DarkActionBar"
这个主题就是Android规范设计风格Material和之前的Theme.AppCompat.DayNight.DarkActionBar没什么大的区别,也都有不带ActionBar的主题风格Theme.AppCompat.DayNight.NoActionBar,Theme.MaterialComponents.DayNight.NoActionBar还有好多种主题风格,以后研究专门讲

 <style name="ss" parent="Theme.AppCompat.DayNight.DarkActionBar">
        <item name="colorPrimary">@color/red</item>//这个设置标题栏的颜色
        <item name="colorPrimaryDark">@color/green</item>//这个设置状态栏的颜色
        <item name="colorAccent">@color/blue</item><!--控制各个控件被选中时的颜色--><!--windowActionBar可以设置没有标题栏-->
        item name="windowActionBar">false</item>
        <!--windowNoTitle可以设置没有标题栏-->
         <item name="windowNoTitle">true</item>
    </style>

方式一:这个可以设置appliction和activty主题风格都可以
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
这2个在主题中可以去掉标题栏
方式二:在代码中使用requestWindowFeature也可以去掉标题栏

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏注意这句一定要写在setContentView()方法的前面,不然会报错的,这个只针对特定的页面Activty
        setContentView(R.layout.activity_main);
    }

方式三:就是Theme.AppCompat.DayNight.NoActionBar直接设配NoActionBar主题风格

二:状态栏
去掉状态栏(状态栏一般不去掉)
方式一:代码实现

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏注意这句一定要写在setContentView()方法的前面,不然会报错的
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);//去掉状态栏,但是变成黑色阴影
        setContentView(R.layout.activity_main);
    }

方式二:主题风格设置全屏
<item name="android:windowFullscreen">true</item>//这些都是针对之前系统版本的

我们要设置全面屏
我们状态栏这只能透明的


    /**
     * 设置状态栏透明,启用全屏模式
     * @param activity
     */
    @TargetApi(19)
    public static void transparencyBar(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = activity.getWindow();
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(Color.TRANSPARENT);
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);

        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            Window window = activity.getWindow();
            window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
    }

针对状态栏修改状态栏的为全面屏,和状态栏的字体颜色变化,变黑,和变白种不同的方法

public class StatusBarUtil {

    /**
     * 修改状态栏为全透明
     * @param activity
     */
    @TargetApi(19)
    public static void transparencyBar(Activity activity){
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = activity.getWindow();
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(Color.TRANSPARENT);

        } else
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            Window window =activity.getWindow();
            window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
                    WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
    }
    

    /**
     *状态栏亮色模式,设置状态栏黑色文字、图标,
     * 适配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android
     * @param activity
     * @return 1:MIUUI 2:Flyme 3:android6.0
     */
    public static int StatusBarLightMode(Activity activity){
        int result=0;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            //小米的亮度模式
            if(MIUISetStatusBarLightMode(activity, true)){
                result=1;
                //魅族的亮度模式
            }else if(FlymeSetStatusBarLightMode(activity.getWindow(), true)){
                result=2;
                //原生
            }else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                activity.getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
                result=3;
            }
        }
        return result;
    }

    /**
     * 已知系统类型时,设置状态栏黑色文字、图标。
     * 适配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android
     * @param activity
     * @param type 1:MIUUI 2:Flyme 3:android6.0
     */
    public static void StatusBarLightMode(Activity activity,int type){
        if(type==1){
            MIUISetStatusBarLightMode(activity, true);
        }else if(type==2){
            FlymeSetStatusBarLightMode(activity.getWindow(), true);
        }else if(type==3){
            activity.getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
        }

    }

    /**
     * 状态栏暗色模式,清除MIUI、flyme或6.0以上版本状态栏黑色文字、图标
     */
    public static void StatusBarDarkMode(Activity activity,int type){
        if(type==1){
            MIUISetStatusBarLightMode(activity, false);
        }else if(type==2){
            FlymeSetStatusBarLightMode(activity.getWindow(), false);
        }else if(type==3){
            activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
        }

    }

    /**
     * 状态栏暗色模式,清除MIUI、flyme或6.0以上版本状态栏黑色文字、图标
     */
    public static int StatusBarDarkMode(Activity activity){
        int result=0;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            //小米的亮度模式
            if(MIUISetStatusBarLightMode(activity, false)){
                result=1;
                //魅族的亮度模式
            }else if(FlymeSetStatusBarLightMode(activity.getWindow(), false)){
                result=2;
                //原生
            }else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
                result=3;
            }
        }
        return result;
    }


    /**
     * 设置状态栏图标为深色和魅族特定的文字风格
     * 可以用来判断是否为Flyme用户
     * @param window 需要设置的窗口
     * @param dark 是否把状态栏文字及图标颜色设置为深色
     * @return  boolean 成功执行返回true
     *
     */
    public static boolean FlymeSetStatusBarLightMode(Window window, boolean dark) {
        boolean result = false;
        if (window != null) {
            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) {

            }
        }
        return result;
    }

    /**
     * 需要MIUIV6以上
     * @param activity
     * @param dark 是否把状态栏文字及图标颜色设置为深色
     * @return  boolean 成功执行返回true
     *
     */
    public static boolean MIUISetStatusBarLightMode(Activity activity, boolean dark) {
        boolean result = false;
        Window window=activity.getWindow();
        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);//清除黑色字体
                }
                result=true;

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    //开发版 7.7.13 及以后版本采用了系统API,旧方法无效但不会报错,所以两个方式都要加上
                    if(dark){
                        activity.getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN| View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
                    }else {
                        activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
                    }
                }
            }catch (Exception e){

            }
        }
        return result;
    }
}

三:自定义标题栏ToolBar
最基本的使用background 设置背景色

<androidx.appcompat.widget.Toolbar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/green"/>

image.png

  <androidx.appcompat.widget.Toolbar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/green"
        app:navigationIcon="@mipmap/ic_launcher"//设置返回按钮
         app:logo="@mipmap/ic_launcher"//logo 添加logo
          app:title="ToolBar标题"//title和subtitle 添加标题和子标题
        app:subtitle="ToolBar子标题"
         app:titleTextColor="#ffffff"//titleTextColor和subtitleTextColor 修改标题和子标题的颜色
        app:subtitleTextColor="#ffffff"
          app:collapseIcon="@mipmap/back"//collapseIcon 设置折叠视图的图标
        >
</androidx.appcompat.widget.Toolbar>

toolBar还可以添加菜单Menu
通过inflateMenu可以添加toolbar的菜单
在res目录下新建文件夹menu,然后创建toolbar_menu文件
image.png

 Toolbar toolbar=findViewById(R.id.toolbar);
        toolbar.inflateMenu(R.menu.toolbar_menu);

toolbar_menu的文件内容

<?xml version="1.0" encoding="utf-8"?>
<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/action_search"
        android:icon="@mipmap/ic_launcher"
        android:title="按钮1"
        app:showAsAction="ifRoom" />

    <item
        android:id="@+id/action_notification"
        android:icon="@mipmap/ic_launcher"
        android:title="按钮2"
        app:showAsAction="ifRoom" />

    <item
        android:id="@+id/action_item_one"
        android:title="按钮3"
        app:showAsAction="never" />

    <item
        android:id="@+id/action_item_two"
        android:title="按钮4"
        app:showAsAction="never" />
</menu>

<!--每个菜单都可以设置特有的属性

orderInCategory
设置菜单项的排列顺序,必须设置大于等于0的整数值。数值小的排列在前,如果值相等,则按照xml中的顺序展现。
title
菜单项的标题。
icon
菜单项的图标。
showAsAction
该属性有五个值,可以混合使用。
always:总是显示在Toolbar上。
ifRoom:如果Toolbar上还有空间,则显示,否则会隐藏在溢出列表中。
never:永远不会显示在Toolbar上,只会在溢出列表中出现。
withText:文字和图标一起显示。
collapseActionView:声明了这个操作视窗应该被折叠到一个按钮中,当用户选择这个按钮时,这个操作视窗展开。一般要配合ifRoom一起使用才会有效。
-->

END:世界上那些最容易的事情中,拖延时间最不费力


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK