精华内容
下载资源
问答
  • 在新的项目中,我按照需求需要设计沉浸状态栏,当然一开始我还不知道这个叫做“沉浸状态栏”,到网上搜索半天都找不到结果。我搜索了“Ionic刘海屏自适应”,“Ionic透明状态栏”等。有时候对我们来说最难的不是...

    在新的项目中,我按照需求需要设计沉浸式状态栏,当然一开始我还不知道这个叫做“沉浸式状态栏”,到网上搜索半天都找不到结果。我搜索了“Ionic刘海屏自适应”,“Ionic透明状态栏”等。有时候对我们来说最难的不是发现问题,而是不知道怎么去搜索。最后可算是找到了,但是网上也是各种各样的答案,各个博主按照他们PO出来的方法都实现了,但是在我这里就是实现不了。因为我发现他们在给方案的时候总是喜欢省略一些步骤,导致新手总是出错。后来经过不断实验,我终于总结出了方法。

    首先声明我的Ionic版本是5,我使用了Capacitor

    第一步:安装插件

    打开你的项目,在终端输入以下代码来安装cordova的状态栏插件

    ionic cordova plugin add cordova-plugin-statusbar

    安装完了过后,按照Capacitor的要求,我们要进行同步,执行下面的代码:

    npx cap sync

    第二步:在app.module.ts中引入

    安装好插件过后,首先要在app.module.ts中引入,省略了一些无关紧要的代码,只保留了与statusbar有关的代码,注意识别:

    import { StatusBar } from '@ionic-native/status-bar/ngx';

    @NgModule({

    providers: [

    StatusBar

    ]

    })

    第三步:在app.component.ts文件中引入,并在初始化的时候进行设置:

    这里也省略了一些无关紧要的代码,只保留了与statusbar有关的代码,注意识别

    import { StatusBar } from '@ionic-native/status-bar/ngx';

    export class AppComponent {

    constructor(private statusBar: StatusBar) {

    this.initializeApp();

    }

    initializeApp() {

    this.platform.ready().then(() => {

    this.statusBar.styleDefault();

    this.statusBar.overlaysWebView(true);

    }

    }

    接下来对项目进行构建,然后运行到我的手机上,很简单,就这几个步骤。就是这样的效果,有图有真相:

    最后就是我实现以后的效果:

    ebf00f22c07a5fc307c6b7c59663d24a.png

    展开全文
  • 沉浸状态栏

    2017-10-09 09:27:21
    http://blog.csdn.net/guolin_blog/article/details/51763825/** * [沉浸状态栏] */ protected void steepStatusBar() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {

    http://blog.csdn.net/guolin_blog/article/details/51763825

    /**
         * [沉浸状态栏]
         */
        protected void steepStatusBar() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                // 透明状态栏
                getWindow().addFlags(
                        WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                // 透明导航栏
                getWindow().addFlags(
                        WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            }
        }
    

    1 适配状态栏
    values-v19/style.xml—对应api19+手机型号在此调用。
    values-v21/style.xml—对应api21+手机型号在此调用。
    Android studio新建values-v19,values-v21
    切换到project下

    这里写图片描述
    命名为values-v19,values-v21,封闭在里面粘贴复制styles.xml
    http://blog.csdn.net/fan7983377/article/details/51604657
    另外一种方法
    1.在res-》values中ids.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <item name="immersiveutil_fake_status_bar_view" type="id" />
    </resources>
    

    2.ImmersiveModeUtil.java

    public class ImmersiveModeUtil {
        private static final int DEFAULT_STATUS_BAR_ALPHA = 112;
        private static final int FAKE_STATUS_BAR_VIEW_ID = R.id.immersiveutil_fake_status_bar_view;
    
        private static int mPreviousSystemUiVisibility;
        /**
         * 0: not support, 1:darkMode, 2: lightMode
         */
        private static int currentStatusBarStyle;
    
        // 判断MIUI系统
        private static boolean sIsMiuiV6;
    
        static {
            try {
                Class<?> sysClass = Class.forName("android.os.SystemProperties");
                Method getStringMethod = sysClass.getDeclaredMethod("get", String.class);
                sIsMiuiV6 = "V6".equals((String) getStringMethod.invoke(sysClass, "ro.miui.ui.version.name"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 全屏Frag
         */
        public static final int FULL_SCREEN_VISIBILITY =
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
                        | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
                        | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
    
    
        /**
         * 布局全屏会占用statusbar区域,通常配合设置状态栏背景为透明色。
         */
        public static final int LAYOUT_STABLE_AND_FULLSCREEN_VISIBILITY =
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
    
        /**
         * 请求全屏,隐藏状态和和导航栏。使用场景:视频播放
         *
         * @param activity
         */
        public static void requestFullScreen(@NonNull Activity activity) {
            setSystemUiVisibility(activity, FULL_SCREEN_VISIBILITY);
        }
    
        /**
         * 退出全屏,进入全屏前,缓存systemui状态
         *
         * @param activity
         */
        public static void quitFullScreen(@NonNull Activity activity) {
            View decorView = activity.getWindow().getDecorView();
            int systemUiVisibility = decorView.getSystemUiVisibility();
            systemUiVisibility &= ~View.SYSTEM_UI_FLAG_FULLSCREEN;
            systemUiVisibility &= ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
            systemUiVisibility &= ~View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
            systemUiVisibility &= ~View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
            systemUiVisibility &= ~View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
            systemUiVisibility &= ~View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
            decorView.setSystemUiVisibility(systemUiVisibility);
        }
    
        /**
         * @param activity
         * @param systemUiVisibility
         */
        public static void setSystemUiVisibility(@NonNull Activity activity, int systemUiVisibility) {
            View decorView = activity.getWindow().getDecorView();
            mPreviousSystemUiVisibility = decorView.getSystemUiVisibility();
            decorView.setSystemUiVisibility(systemUiVisibility);
        }
    
        /**
         * 恢复
         *
         * @param activity
         */
        public static void restorePreviousSystemUiVisibility(@NonNull Activity activity) {
            if (mPreviousSystemUiVisibility != 0) {
                activity.getWindow().getDecorView().setSystemUiVisibility(mPreviousSystemUiVisibility);
            } else {
                setDefaultImmersiveMode(activity);
            }
        }
    
        /**
         * App默认的沉浸式默认
         *
         * @param activity
         */
        public static void setDefaultImmersiveMode(@NonNull Activity activity) {
            final boolean darkMode = setStatusBarDarkMode(activity, true);
            if (darkMode) {
                setStatusBarBgColor(activity, Color.WHITE);
            }
        }
    
        /**
         * 设置状态栏背景透明且layoutFullscreen
         *
         * @param activity
         */
        public static void setStatusBarTransparent(@NonNull Activity activity) {
            final Window window = activity.getWindow();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                window.setStatusBarColor(Color.TRANSPARENT);
                final int systemUiVisibility = window.getDecorView().getSystemUiVisibility();
                window.getDecorView().setSystemUiVisibility(systemUiVisibility | LAYOUT_STABLE_AND_FULLSCREEN_VISIBILITY);
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                activity.getWindow()
                        .setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            }
        }
    
        /**
         * 设置状态栏颜色
         *
         * @param activity 需要设置的 activity
         * @param color    状态栏颜色值
         */
        public static void setStatusBarBgColor(@NonNull Activity activity, @ColorInt int color) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                activity.getWindow().setStatusBarColor(color);
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
                View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);
                if (fakeStatusBarView != null) {
                    if (fakeStatusBarView.getVisibility() == View.GONE) {
                        fakeStatusBarView.setVisibility(View.VISIBLE);
                    }
                    fakeStatusBarView.setBackgroundColor(color);
                } else {
                    decorView.addView(createStatusBarView(activity, color));
                }
                setRootView(activity);
            }
        }
    
        /**
         * 先判断主流系统,然后MIUI系统,最后Flyme
         *
         * @param activity
         * @param isFontColorDark 深色字体(Light)模式
         * @return 是否设置成功
         */
        @TargetApi(Build.VERSION_CODES.M)
        public static boolean setStatusBarDarkMode(@NonNull Activity activity, boolean isFontColorDark) {
            boolean result = setCommonStatusBarDarkMode(activity, isFontColorDark);
            if (!result) {
                result = setMIUIStatusBarDarkIcon(activity, isFontColorDark);
    
                if (!result) {
                    result = setMeizuStatusBarDarkIcon(activity, isFontColorDark);
                }
            }
            if (result) {
                currentStatusBarStyle = isFontColorDark ? 2 : 1;
            }
            return result;
        }
    
        /**
         * 生成一个和状态栏大小相同的半透明矩形条
         *
         * @param activity 需要设置的activity
         * @param color    状态栏颜色值
         * @return 状态栏矩形条
         */
        private static View createStatusBarView(Activity activity, @ColorInt int color) {
            // 绘制一个和状态栏一样高的矩形
            View statusBarView = new View(activity);
            LinearLayout.LayoutParams params =
                    new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight());
            statusBarView.setLayoutParams(params);
            statusBarView.setBackgroundColor(color);
            statusBarView.setId(FAKE_STATUS_BAR_VIEW_ID);
            return statusBarView;
        }
    
        /**
         * 设置根布局参数
         */
        private static void setRootView(Activity activity) {
            ViewGroup parent = activity.findViewById(android.R.id.content);
            for (int i = 0, count = parent.getChildCount(); i < count; i++) {
                View childView = parent.getChildAt(i);
                if (childView instanceof ViewGroup) {
                    childView.setFitsSystemWindows(true);
                    ((ViewGroup) childView).setClipToPadding(true);
                }
            }
        }
    
        /**
         * 计算状态栏颜色
         *
         * @param color color值
         * @param alpha alpha值
         * @return 最终的状态栏颜色
         */
        private static int calculateStatusColor(@ColorInt int color, int alpha) {
            if (alpha == 0) {
                return color;
            }
            float a = 1 - alpha / 255f;
            int red = color >> 16 & 0xff;
            int green = color >> 8 & 0xff;
            int blue = color & 0xff;
            red = (int) (red * a + 0.5);
            green = (int) (green * a + 0.5);
            blue = (int) (blue * a + 0.5);
            return 0xff << 24 | red << 16 | green << 8 | blue;
        }
    
        /**
         * 已在style中配置
         * 官方及主流rom
         *
         * @param activity
         */
        public static boolean setCommonStatusBarDarkMode(@NonNull Activity activity, boolean isFontColorDark) {
            boolean result = false;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                View decor = activity.getWindow().getDecorView();
                int ui = decor.getSystemUiVisibility();
                if (isFontColorDark) {
                    ui |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
                } else {
                    ui &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
                }
                decor.setSystemUiVisibility(ui);
                // api>=23 默认成功
                result = true;
            }
            return result;
        }
    
        /**
         * set status bar darkmode
         *
         * @param isFontColorDark
         * @param activity
         */
        public static boolean setMIUIStatusBarDarkIcon(@NonNull Activity activity, boolean isFontColorDark) {
            boolean result = false;
            if (sIsMiuiV6) {
                Class<? extends Window> clazz = activity.getWindow().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);
                    extraFlagField.invoke(activity.getWindow(), isFontColorDark ? darkModeFlag : 0, darkModeFlag);
                    result = true;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return result;
        }
    
        /**
         * 修改魅族状态栏字体颜色 Flyme 4.0
         */
        private static boolean setMeizuStatusBarDarkIcon(@NonNull Activity activity, boolean isFontColorDark) {
            boolean result = false;
            try {
                WindowManager.LayoutParams lp = activity.getWindow().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 (isFontColorDark) {
                    value |= bit;
                } else {
                    value &= ~bit;
                }
                meizuFlags.setInt(lp, value);
                activity.getWindow().setAttributes(lp);
                result = true;
            } catch (Exception e) {
                //e.printStackTrace();
            }
            return result;
        }
    
        /**
         * @return 1:不支持,0:支持
         */
        public static int canSetStatusBarStyle() {
            int status = 1;
            // 成功设置过,或者API>=23
            if (currentStatusBarStyle != 0 || Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                status = 0;
            }
            return status;
        }
    
        /**
         * Return the status bar's height.
         *
         * @return the status bar's height
         */
        public static int getStatusBarHeight() {
            Resources resources = Resources.getSystem();
            int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
            return resources.getDimensionPixelSize(resourceId);
        }
    
    }
    
    

    参考文章

    展开全文
  • 记得之前有朋友在留言里让我写一篇关于沉浸状态栏的文章,正巧我确实有这个打算,那么本篇就给大家带来一次沉浸状态栏的微技巧讲解。 其实说到沉浸状态栏这个名字我也是感到很无奈,真不知道这种叫法是谁先...

    转载自郭神:http://blog.csdn.net/guolin_blog/article/details/51763825


    记得之前有朋友在留言里让我写一篇关于沉浸式状态栏的文章,正巧我确实有这个打算,那么本篇就给大家带来一次沉浸式状态栏的微技巧讲解。

    其实说到沉浸式状态栏这个名字我也是感到很无奈,真不知道这种叫法是谁先发起的。因为Android官方从来没有给出过沉浸式状态栏这样的命名,只有沉浸式模式(Immersive Mode)这种说法。而有些人在没有完全了解清楚沉浸模式到底是什么东西的情况下,就张冠李戴地认为一些系统提供的状态栏操作就是沉浸式的,并且还起了一个沉浸式状态栏的名字。

    比如之前就有一个QQ群友问过我,像饿了么这样的沉浸式状态栏效果该如何实现?

    这个效果其实就是让背景图片可以利用系统状态栏的空间,从而能够让背景图和状态栏融为一体。

    本篇文章当中我会教大家如何实现这样的效果,但这个真的不叫沉浸式状态栏。因此,这算是一篇技术+普及的文章吧,讲技术的同时也纠正一下大家之前错误的叫法。

    什么是沉浸式?

    先来分析一下叫错的原因吧,之所以很多人会叫错,是因为根本就不了解沉浸式是什么意思,然后就人云亦云跟着叫了。那么沉浸式到底是什么意思呢?

    根据百度百科上的定义,沉浸式就是要给用户提供完全沉浸的体验,使用户有一种置身于虚拟世界之中的感觉。

    比如说现在大热的VR就是主打的沉浸式体验。

    那么对应到Android操作系统上面,怎样才算是沉浸式体验呢?这个可能在大多数情况下都是用不到的,不过在玩游戏或者看电影的时候就非常重要了。因为游戏或者影视类的应用都希望能让用户完全沉浸在其中,享受它们提供的娱乐内容,但如果这个时候在屏幕的上方还显示一个系统状态栏的话,可能就会让用户分分钟产生跳戏的感觉。

    那么我们来看一下比较好的游戏都是怎么实现的,比如说海岛奇兵:

    海岛奇兵的这种模式就是典型的沉浸式模式,它的整个屏幕中显示都是游戏的内容,没有状态栏也没有导航栏,用户玩游戏的时候就可以完全沉浸在游戏当中,而不会被一些系统的界面元素所打扰。

    然后我们再来看一下爱奇艺的实现:

    同样也是类似的,爱奇艺将整个屏幕作为影视的展示区,用户在看电影的时候眼中就只会有电影的内容,这样就不会被其他一些无关的东西所分心。

    这才是沉浸式模式的真正含义,而所谓的什么沉浸式状态栏纯粹就是在瞎叫,完全都没搞懂“沉浸式” 这三个字是什么意思。

    不过虽然听上去好像是很高大上的沉浸式效果,实际看上去貌似就是将内容全屏化了而已嘛。没错,Android沉浸式模式的本质就是全屏化,不过我们今天的内容并不仅限于此,因为还要实现饿了么那样的状态栏效果。那么下面我们就开始来一步步学习吧。

    隐藏状态栏

    一个Android应用程序的界面上其实是有很多系统元素的,观察下图:

    可以看到,有状态栏、ActionBar、导航栏等。而打造沉浸式模式的用户体验,就是要将这些系统元素全部隐藏,只留下主体内容部分。

    比如说我现在新建了一个空项目,然后修改布局文件中的代码,在里面加入一个ImageView,如下所示:

    <code class="language-xml hljs  has-numbering"><span class="hljs-tag"><<span class="hljs-title">RelativeLayout
    </span>    <span class="hljs-attribute">xmlns:android</span>=<span class="hljs-value">"http://schemas.android.com/apk/res/android"</span>
        <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span>
        <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"match_parent"</span>></span>
    
        <span class="hljs-tag"><<span class="hljs-title">ImageView
    </span>        <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"match_parent"</span>
            <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"match_parent"</span>
            <span class="hljs-attribute">android:src</span>=<span class="hljs-value">"@drawable/bg"</span>
            <span class="hljs-attribute">android:scaleType</span>=<span class="hljs-value">"centerCrop"</span> /></span>
    
    <span class="hljs-tag"></<span class="hljs-title">RelativeLayout</span>></span></code>

    这里将ImageView的宽和高都设置成match_parent,让图片充满屏幕。现在运行一下程序,效果如下图所示。

    如果你将图片理解成游戏或者电影界面的话,那这个体验离沉浸式就差得太远了,至少状态栏和ActionBar得要隐藏起来了吧?没关系,我们一步步进行优化,并且在优化中学习。

    隐藏状态栏和ActionBar的方式在4.1系统之上和4.1系统之下还是不一样的,这里我就不准备考虑4.1系统之下的兼容性了,因为过于老的系统根本就没有提供沉浸式体验的支持。

    修改MainActivity中的代码,如下所示:

    <code class="language-java hljs  has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MainActivity</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AppCompatActivity</span> {</span>
        <span class="hljs-annotation">@Override</span>
        <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span>(Bundle savedInstanceState) {
            <span class="hljs-keyword">super</span>.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            View decorView = getWindow().getDecorView();
            <span class="hljs-keyword">int</span> option = View.SYSTEM_UI_FLAG_FULLSCREEN;
            decorView.setSystemUiVisibility(option);
            ActionBar actionBar = getSupportActionBar();
            actionBar.hide();
        }
    }</code>

    这里先调用getWindow().getDecorView()方法获取到了当前界面的DecorView,然后调用它的setSystemUiVisibility()方法来设置系统UI元素的可见性。其中,SYSTEM_UI_FLAG_FULLSCREEN表示全屏的意思,也就是会将状态栏隐藏。另外,根据Android的设计建议,ActionBar是不应该独立于状态栏而单独显示的,因此状态栏如果隐藏了,我们同时也需要调用ActionBar的hide()方法将ActionBar也进行隐藏。

    现在重新运行一下程序,效果如下图所示。

    这样看上去就有点沉浸式效果的模样了。

    虽说这才是正统的沉浸式含义,但有些朋友可能想实现的就是饿了么那样的状态栏效果,而不是直接把整个系统状态栏给隐藏掉,那么又该如何实现呢?

    其实也很简单,只需要借助另外一种UI Flag就可以了,如下所示:

    <code class="language-java hljs  has-numbering"><span class="hljs-keyword">super</span>.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    <span class="hljs-keyword">if</span> (Build.VERSION.SDK_INT >= <span class="hljs-number">21</span>) {
        View decorView = getWindow().getDecorView();
        <span class="hljs-keyword">int</span> option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
        decorView.setSystemUiVisibility(option);
        getWindow().setStatusBarColor(Color.TRANSPARENT);
    }
    ActionBar actionBar = getSupportActionBar();
    actionBar.hide();</code>

    首先需要注意,饿了么这样的效果是只有5.0及以上系统才支持,因此这里先进行了一层if判断,只有系统版本大于或等于5.0的时候才会执行下面的代码。

    接下来我们使用了SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN和SYSTEM_UI_FLAG_LAYOUT_STABLE,注意两个Flag必须要结合在一起使用,表示会让应用的主体内容占用系统状态栏的空间,最后再调用Window的setStatusBarColor()方法将状态栏设置成透明色就可以了。

    现在重新运行一下代码,效果如下图所示。

    可以看到,类似于饿了么的状态栏效果就成功实现了。

    再声明一次,这种效果不叫沉浸式状态栏,也完全没有沉浸式状态栏这种说法,我们估且可以把它叫做透明状态栏效果吧。

    隐藏导航栏

    现在我们已经成功实现隐藏状态栏的效果了,不过屏幕下方的导航栏还比较刺眼,接下来我们就学习一下如何将导航栏也进行隐藏。

    其实实现的原理都是一样的,隐藏导航栏也就是使用了不同的UI Flag而已,修改MainActivity中的代码,如下所示:

    <code class="language-java hljs  has-numbering"><span class="hljs-keyword">super</span>.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    View decorView = getWindow().getDecorView();
    <span class="hljs-keyword">int</span> option = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_FULLSCREEN;
    decorView.setSystemUiVisibility(option);
    ActionBar actionBar = getSupportActionBar();
    actionBar.hide();</code>

    这里我们同时使用了SYSTEM_UI_FLAG_HIDE_NAVIGATION和SYSTEM_UI_FLAG_FULLSCREEN,这样就可以将状态栏和导航栏同时隐藏了。现在重新运行一下程序,效果如图所示。

    这次看上去好像终于是完全全屏化了,但其实上这离真正的沉浸式模式还差得比较远,因为在这种模式下,我们触摸屏幕的任意位置都会退出全屏。

    这显然不是我们想要的效果,因此这种模式的使用场景比较有限。

    除了隐藏导航栏之外,我们同样也可以实现和刚才透明状态栏类似的效果,制作一个透明导航栏:

    <code class="language-java hljs  has-numbering"><span class="hljs-keyword">super</span>.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    <span class="hljs-keyword">if</span> (Build.VERSION.SDK_INT >= <span class="hljs-number">21</span>) {
        View decorView = getWindow().getDecorView();
        <span class="hljs-keyword">int</span> option = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
        decorView.setSystemUiVisibility(option);
        getWindow().setNavigationBarColor(Color.TRANSPARENT);
        getWindow().setStatusBarColor(Color.TRANSPARENT);
    }
    ActionBar actionBar = getSupportActionBar();
    actionBar.hide();</code>

    这里使用了SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION,表示会让应用的主体内容占用系统导航栏的空间,然后又调用了setNavigationBarColor()方法将导航栏设置成透明色。现在重新运行一下程序,效果如下图所示。

    真正的沉浸式模式

    虽说沉浸式导航栏这个东西是被很多人误叫的一种称呼,但沉浸式模式的确是存在的。那么我们如何才能实现像海岛奇兵以及爱奇艺那样的沉浸式模式呢?

    首先你应该确定自己是否真的需要这个功能,因为除了像游戏或者视频软件这类特殊的应用,大多数的应用程序都是用不到沉浸式模式的。

    当你确定要使用沉浸式模式,那么只需要重写Activity的onWindowFocusChanged()方法,然后加入如下逻辑即可:

    <code class="language-java hljs  has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MainActivity</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AppCompatActivity</span> {</span>
    
        <span class="hljs-annotation">@Override</span>
        <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span>(Bundle savedInstanceState) {
            <span class="hljs-keyword">super</span>.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
    
        <span class="hljs-annotation">@Override</span>
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onWindowFocusChanged</span>(<span class="hljs-keyword">boolean</span> hasFocus) {
            <span class="hljs-keyword">super</span>.onWindowFocusChanged(hasFocus);
            <span class="hljs-keyword">if</span> (hasFocus && Build.VERSION.SDK_INT >= <span class="hljs-number">19</span>) {
                View decorView = getWindow().getDecorView();
                decorView.setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
            }
        }
    
    }</code>

    沉浸式模式的UI Flag就这些,也没什么好解释的,如果你需要实现沉浸式模式,直接将上面的代码复制过去就行了。需要注意的是,只有在Android 4.4及以上系统才支持沉浸式模式,因此这里也是加入了if判断。

    另外,为了让我们的界面看上去更像是游戏,这里我将MainActivity设置成了横屏模式:

    <code class="language-xml hljs  has-numbering"><span class="hljs-tag"><<span class="hljs-title">activity</span> <span class="hljs-attribute">android:name</span>=<span class="hljs-value">".MainActivity"</span> 
              <span class="hljs-attribute">android:screenOrientation</span>=<span class="hljs-value">"landscape"</span>></span>
        ...
    <span class="hljs-tag"></<span class="hljs-title">activity</span>></span></code>

    这样我们就实现类似于海岛奇兵和爱奇艺的沉浸式模式效果了,如下图所示。

    可以看到,界面默认情况下是全屏的,状态栏和导航栏都不会显示。而当我们需要用到状态栏或导航栏时,只需要在屏幕顶部向下拉,或者在屏幕右侧向左拉,状态栏和导航栏就会显示出来,此时界面上任何元素的显示或大小都不会受影响。过一段时间后如果没有任何操作,状态栏和导航栏又会自动隐藏起来,重新回到全屏状态。

    这就是最标准的沉浸式模式。

    展开全文
  • 解决沉浸状态栏和华为虚拟键冲突,7.0后状态栏变灰的问题,有详细注释,还有kotlin版本的代码和java的代码
  • 沉浸状态栏介绍 沉浸状态栏式Android 4.4 引入的一个机制,可以将手机顶端的状态栏颜色融入当前app的界面中,而不至于和app的界面以及配色有着明显的割裂。 在如今手机全面屏化的促进下,并且由于安卓手机的...

    沉浸式状态栏介绍

    沉浸式状态栏式Android 4.4 引入的一个机制,可以将手机顶端的状态栏颜色融入当前app的界面中,而不至于和app的界面以及配色有着明显的割裂。
    沉浸式状态栏效果示意图

    在如今手机全面屏化的促进下,并且由于安卓手机的碎片化各家的状态栏背景颜色可能还不一定一致。在不进行沉浸式状态栏适配的app在大屏占比的手机上就会显得异常突兀,下面我就介绍一种最快速方便的将当前app和顶部状态栏实现沉浸式体验的方法。


    沉浸式状态栏实现

    首先需要明确使用下面的方法需要安卓4.4 KITKAT以上的系统,具体实现仅仅需要两步就可以实现。


    步骤一

    首先我们需要在想要实现沉浸式状态栏的app界面的页面布局的xml代码中加入以下两句代码:

    android:fitsSystemWindows=“true”
    android:clipToPadding=“true”

    具体代码的添加位置为当前Activity的布局xml文件的除了根布局以外的,最上方和状态栏接触的布局位置。下面我以自己登录界面的代码进行演示,大家只需要关注上方有关渐变背景的相对布局代码,我这个界面主要是一个顶部的切换栏,中间有登录和注册的切换TextView,具体的登录和注册页面通过inflate的方式添加进底部的content。

    xml代码如下

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="#ffffff"
        android:orientation="vertical" >
    
       <LinearLayout
           android:id="@+id/title_back"
           android:fitsSystemWindows="true" <!--渐变代码添加位置-->
           android:clipToPadding="true"
           android:layout_width="match_parent"
           android:layout_height="100dp"
           android:background="@drawable/login_title_background"
           android:layout_weight="1.0"
           android:orientation="vertical">
       </LinearLayout>
    
        <LinearLayout
            android:id="@+id/title_switch"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:orientation="horizontal">
            <LinearLayout
                android:id="@+id/ly_login"
                android:layout_width="10dp"
                android:layout_height="50dp"
                android:layout_weight="1.0"
                android:orientation="vertical"
                android:gravity="center_horizontal|center_vertical">
                <TextView
                    android:id="@+id/tv_login"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="登录"
                    android:textStyle="bold"
                    android:textSize="20sp"
                    android:textColor="#333333"/>
                <LinearLayout
                    android:id="@+id/login_bar"
                    android:layout_width="70dp"
                    android:layout_height="4dp"
                    android:layout_marginTop="5dp"
                    android:orientation="vertical"
                    android:background="#FFBF54">
                </LinearLayout>
            </LinearLayout>
    
            <LinearLayout
                android:id="@+id/ly_regist"
                android:layout_width="10dp"
                android:layout_height="50dp"
                android:layout_weight="1.0"
                android:orientation="vertical"
                android:gravity="center_horizontal|center_vertical">
    
                <TextView
                    android:id="@+id/tv_regist"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:clickable="true"
                    android:text="注册"
                    android:textStyle="bold"
                    android:textSize="20sp"
                    android:textColor="#CCCCCC"/>
                <LinearLayout
                    android:id="@+id/regist_bar"
                    android:layout_width="70dp"
                    android:layout_height="4dp"
                    android:layout_marginTop="5dp"
                    android:orientation="vertical"
                    android:background="#FFFFFF">
                </LinearLayout>
    
            </LinearLayout>
    
            <LinearLayout
                android:layout_width="10dp"
                android:layout_height="40dp"
                android:layout_weight="1.0"
                android:gravity="center_horizontal|center_vertical">
            </LinearLayout>
    
        </LinearLayout>
    
        <LinearLayout
            android:id="@+id/login_content"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:background="#FFFFFF"
            android:layout_weight="3.0"
            android:orientation="vertical">
        </LinearLayout>
    
    </LinearLayout>
    

    上诉xml代码对应的页面布局效果如下:

    xml界面


    步骤二

    第二步需要在对应的Activity的Java代码中,onCreate()在setContentView之后添加以下的语句:

      if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT) {
     		getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
      }
    

    具体的位置下面以我自己的项目部分文件做展示,具体如下:

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            requestWindowFeature(Window.FEATURE_NO_TITLE);
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_login);
            if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT) {//沉浸渐变代码添加位置,判断当前sdk版本
                getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            }
            login_view= LayoutInflater.from(this).inflate(R.layout.login_tab, null);
            regist_view= LayoutInflater.from(this).inflate(R.layout.regist_tab, null);
            switch_content = (LinearLayout) findViewById(R.id.login_content);
            switch_content.addView(login_view);
       }
    

    至此两步已经完成,重新编译就可以实现上述效果。需要强调的是当前的Activity的style设置的 NoActionBar 。

    展开全文
  • 这是一个为Android App 设置状态栏的工具类, 可以在4.4及其以上系统中实现 沉浸状态栏/状态栏变色,支持设置状态栏透明度,满足你司设计师的各种要求。本着不重复造轮子的原则,在网上找到了一个工具类,方便需要...
  • android 沉浸状态栏下fitSystemWindow与键盘挡住输入框问题 在将状态栏改为沉浸时遇到了如下一个问题:fitsSystemWindows设置为true后,界面就无法全屏,因为顶部有一个状态栏高度的padding;不设置...
  • QQ实现了沉浸状态栏的效果,如图:  如图,好多应用如金山词霸等也实现了这样的效果。这样的效果很酷炫,其实设置很简单。  不过要说明的是,这种效果只能在API19以及以上版本中才能够做到。  如果想让...
  • 原文 -- StatusBarUtil 状态栏工具类(实现沉浸... App 设置状态栏的工具类, 可以在4.4及其以上系统中实现 沉浸状态栏/状态栏变色,支持设置状态栏透明度,满足你司设计师的各种要求(雾)。 Sample 下载 特性:
  • Android沉浸状态栏(5.0以上系统) 请注明出处:http://blog.csdn.net/qq_23179075/article/details/53670289 沉浸状态栏可以分为两种: 1.直接给状态栏设置颜色 (如下图:) java代码形式: if (Build....
  • 沉浸状态栏 :Android 5.0以上才会支持沉浸状态栏效果。 下面就建立一个默认的项目。1.状态栏(背景色是蓝色,字体图标是白色的)2.ActionBar,一般都不用的 3.内容 4.虚拟键。 所谓沉浸状态栏就是只有3着...
  • Flutter中沉浸状态栏的设置 沉浸状态栏是什么? 状态栏是指Android手机顶部显示手机...在flutter项目目录下找到android主入口页面MainActivity.kt或MainActivity.java,判断一下版本号然后将状态栏颜色修改设置成
  • Android4.4沉浸状态栏全解析

    千次阅读 2016-06-24 12:49:24
    首先先说明沉浸状态栏的原理: 沉浸主要是通过设置value-v19的styles的android:windowTranslucentStatus 使状态栏透明,离状态栏最近的view则会填充状态栏 注意,这个是api19才能用的。 下面是步骤: 1.定义颜色和...
  • window.setStatusBarColor(color);

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,379
精华内容 1,351
关键字:

java沉浸状态栏

java 订阅