Android使用fitsSystemWindows属性实现–状态栏【status_bar】各版本适配方案

简介:

Android使用fitsSystemWindows属性实现–状态栏【status_bar】各版本适配方案 
首先我们看下qq的status bar在各个android版本系统中适配:

1.Android5.0以上:半透明(APP 的内容不被上拉到状态) 
这里写图片描述

2.Android4.4以上:全透明(APP 的内容不被上拉到状态) 
这里写图片描述

3.Android4.4以下:不占据status bar 
这里写图片描述

这里我们就按照qq在各个android的版本显示进行适配: 
1.Android5.0以上:material design风格,半透明(APP 的内容不被上拉到状态) 
2.Android4.4(kitkat)以上至5.0:全透明(APP 的内容不被上拉到状态) 
3.Android4.4(kitkat)以下:不占据status bar

主题: 
使用Theme.AppCompat.Light.NoActionBar(toolbar的兼容主题):既可以适配使用toolbar(由于google已经不再建议使用action bar了,而是推荐使用toolbar,且toolbar的使用更加的灵活,所以toolbar和actionbar的选择也没什么好纠结的)和不使用toolbar的情况(即自定义topBar布局)。

fitSystemWindows属性: 
官方描述: 
Boolean internal attribute to adjust view layout based on system windows such as the status bar. If true, adjusts the padding of this view to leave space for the system windows. Will only take effect if this view is in a non-embedded activity. 
简单描述: 
这个一个boolean值的内部属性,让view可以根据系统窗口(如status bar)来调整自己的布局,如果值为true,就会调整view的paingding属性来给system windows留出空间…. 
实际效果: 
当status bar为透明或半透明时(4.4以上),系统会设置view的paddingTop值为一个适合的值(status bar的高度)让view的内容不被上拉到状态栏,当在不占据status bar的情况下(4.4以下)会设置paddingTop值为0(因为没有占据status bar所以不用留出空间)。

具体适配方案(一边看代码一边解析): 
activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <!--toolbar-->
    <include
        layout="@layout/mytoolbar_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:gravity="center"
        android:text="ThinkCool" />
</LinearLayout>

这里我们include了一个mytoolbar_layout的布局:

mytoolbar_layout.xml:

<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/my_toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/colorPrimary"
    android:fitsSystemWindows="true"
    android:minHeight="?attr/actionBarSize"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

在mytoolbar_layout.xml里:布局一个 android.support.v7.widget.Toolbar(使用支持包里的toolbar可以兼容低版本android系统),并设置minHeight=”?attr/actionBarSize”和fitSystemWindows为true。

MainActivity.java:

package com.thinkcool.statusbaradapt;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;

public class MainActivity extends BaseActivity {
    Toolbar toolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //让toolbar同actionbar一样使用,include自定义的topbar时注释到下面两句
        toolbar = (Toolbar) findViewById(R.id.my_toolbar);
        setSupportActionBar(toolbar);
    }
}

在MainActivity.java里,继承BaseAcitivity(后面描述),实例化toolbar并调用setSupportActionBar,之后就可以让toolbar像action bar一样使用了。

BaseActivity.java:

package com.thinkcool.statusbaradapt;

import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Window;
import android.view.WindowManager;

public class BaseActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            Window window = getWindow();
            // Translucent status bar
            window.setFlags(
                    WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
                    WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
    }
}

在BaseActivity.java里:我们通过判断当前sdk_int大于4.4(kitkat),则通过代码的形式设置status bar为透明(这里其实可以通过values-v19 的sytle.xml里设置windowTranslucentStatus属性为true来进行设置,但是在某些手机会不起效,所以采用代码的形式进行设置)。还需要注意的是我们这里的AppCompatAcitivity是android.support.v7.app.AppCompatActivity支持包中的AppCompatAcitivity,也是为了在低版本的android系统中兼容toolbar。

AndroidManifest.xml中:使用Theme.AppCompat.Light.NoActionBar主题

....
<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="Theme.AppCompat.Light.NoActionBar">
...

最后build.gradle中引入v7支持库(需要注意v7版本得大于21): 
compile ‘com.android.support:appcompat-v7:23.1.1’

看看效果吧(同qq状态栏效果,依次是:不透明(4.4以下),透明(4.4以上),半透明(5.0以上)): 
Android4.4以下:不占据status bar 
这里写图片描述

Android4.4以上:全透明(APP 的内容不被上拉到状态) 
这里写图片描述

Android5.0以上:半透明(APP 的内容不被上拉到状态) 
这里写图片描述 
这套适配方案的好处: 
1.通过include mytoolbar.xml和mytopbar.xml可以方便的在使用toolbar和使用自定义topbar中进行抉择。 
2.使用fitSystemWindows属性让系统帮我们自动适配不同情况下的status bar,让我们的view的paddingTop获取到一个合理的值。(还有其他的方案是通过手动设置paddingTop的值来进行适配的:在values-v19里设置paddingTop值为25dp,在values里设置为0dp,但是在某些自定义的rom里status bar的高度是被有修改过的。还有就是通过自定义继承toolbar,在代码里动态获取status bar的高度并设置paddingTop的值,但这样又弄得太麻烦了)。

自定义topBar的情况(因为我们的UI设计师不一定跟得上material design的步伐,而且总是在有着不一样的设计风格,这个时候自定义topbar就最好了如:qq的topbar就是自定义的):

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <!--toolbar-->
    <!--<include-->
        <!--layout="@layout/mytoolbar_layout"-->
        <!--android:layout_width="match_parent"-->
        <!--android:layout_height="wrap_content" />-->
    <!--自定义topbar-->
    <include
        layout="@layout/mytopbar_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:gravity="center"
        android:text="ThinkCool" />
</LinearLayout>

在activity_main.xml里:include自定义的mytopbar_layout.

mytopbar_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/colorPrimary"
    android:minHeight="?attr/actionBarSize"
    android:gravity="center"
    android:fitsSystemWindows="true"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="8dp"
        android:gravity="center"
        android:orientation="horizontal">
        <ImageView
            android:id="@+id/top_left"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/back" />

        <TextView
            android:id="@+id/top_center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_weight="1"
            android:gravity="center"
            android:text="登陆"
            android:textSize="16sp" />

        <ImageView
            android:id="@+id/top_right"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/add" />
    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:background="@android:color/darker_gray" />
</LinearLayout>

修改MainActivity.java:
package com.thinkcool.statusbaradapt;

import android.os.Bundle;
import android.support.v7.widget.Toolbar;

public class MainActivity extends BaseActivity {
    Toolbar toolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //让toolbar同actionbar一样使用,include自定义的topbar时注释到下面两句
//        toolbar = (Toolbar) findViewById(R.id.my_toolbar);
//        setSupportActionBar(toolbar);
    }
}

MainActivity.java里:我们注释掉了setSupportActionBar(因为这是我们自定义的topbar). 
同样看看实现效果吧: 
Android4.4以下:不占据status bar 
这里写图片描述

Android4.4以上:全透明(APP 的内容不被上拉到状态) 
这里写图片描述

Android5.0以上:半透明(APP 的内容不被上拉到状态) 
这里写图片描述

最后代码上传gitHub(欢迎fork,加星): 
https://github.com/CoolThink/StatusBarAdapt.git

相关文章
|
2月前
|
数据采集 监控 API
告别手动埋点!Android 无侵入式数据采集方案深度解析
传统的Android应用监控方案需要开发者在代码中手动添加埋点,不仅侵入性强、工作量大,还难以维护。本文深入探讨了基于字节码插桩技术的无侵入式数据采集方案,通过Gradle插件 + AGP API + ASM的技术组合,实现对应用性能、用户行为、网络请求等全方位监控,真正做到零侵入、易集成、高稳定。
491 39
|
5月前
|
存储 机器学习/深度学习 API
Android API Level 到底是什么?和安卓什么关系?应用发布如何知道自己的版本?优雅草卓伊凡
Android API Level 到底是什么?和安卓什么关系?应用发布如何知道自己的版本?优雅草卓伊凡
831 31
Android API Level 到底是什么?和安卓什么关系?应用发布如何知道自己的版本?优雅草卓伊凡
|
7月前
|
Android开发 开发者
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
本文详细介绍了如何通过自定义 `attrs.xml` 文件实现 Android 自定义 View 的属性配置。以一个包含 TextView 和 ImageView 的 DemoView 为例,讲解了如何使用自定义属性动态改变文字内容和控制图片显示隐藏。同时,通过设置布尔值和点击事件,实现了图片状态的切换功能。代码中展示了如何在构造函数中解析自定义属性,并通过方法 `setSetting0n` 和 `setbackeguang` 实现功能逻辑的优化与封装。此示例帮助开发者更好地理解自定义 View 的开发流程与 attrs.xml 的实际应用。
191 2
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
|
人工智能 搜索推荐 物联网
Android系统版本演进与未来展望####
本文深入探讨了Android操作系统从诞生至今的发展历程,详细阐述了其关键版本迭代带来的创新特性、用户体验提升及对全球移动生态系统的影响。通过对Android历史版本的回顾与分析,本文旨在揭示其成功背后的驱动力,并展望未来Android可能的发展趋势与面临的挑战,为读者呈现一个既全面又具深度的技术视角。 ####
|
8月前
|
数据采集 JSON 网络安全
移动端数据抓取:Android App的TLS流量解密方案
本文介绍了一种通过TLS流量解密技术抓取知乎App热榜数据的方法。利用Charles Proxy解密HTTPS流量,分析App与服务器通信内容;结合Python Requests库模拟请求,配置特定请求头以绕过反爬机制。同时使用代理IP隐藏真实IP地址,确保抓取稳定。最终成功提取热榜标题、内容简介、链接等信息,为分析热点话题和用户趋势提供数据支持。此方法也可应用于其他Android App的数据采集,但需注意选择可靠的代理服务。
342 11
移动端数据抓取:Android App的TLS流量解密方案
|
10月前
|
移动开发 安全 Java
Android历史版本与APK文件结构
通过以上内容,您可以全面了解Android的历史版本及其主要特性,同时掌握APK文件的结构和各部分的作用。这些知识对于理解Android应用的开发和发布过程非常重要,也有助于在实际开发中进行高效的应用管理和优化。希望这些内容对您的学习和工作有所帮助。
1018 83
|
8月前
|
Java API 开发工具
Android cmdline-tools版本与最小JDK的关系
总的来说,Android的命令行工具和JDK之间的关系就像是一场舞会,两者需要彼此配合,才能共同创造出美妙的舞蹈。如果选择了不合适的舞伴(即不兼容的版本),可能会导致舞蹈中的步伐混乱,甚至无法完成舞蹈。而即使选择了合适的舞伴,也需要考虑舞伴的舞蹈技巧(即性能和稳定性),才能确保舞蹈的完美表现。因此,选择合适的Android命令行工具和JDK版本,是每一个Android开发者都需要面对的重要决定。
262 13
|
9月前
|
安全 开发工具 Android开发
【Android Git】Git版本回退方式
在实际操作中,选择合适的版本回退方式,可以有效地管理代码版本,提高开发效率和代码质量。
512 26
|
10月前
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
660 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
开发框架 Dart 前端开发
Android 跨平台方案对比之Flutter 和 React Native
本文对比了 Flutter 和 React Native 这两个跨平台移动应用开发框架。Flutter 使用 Dart 语言,提供接近原生的性能和丰富的组件库;React Native 则基于 JavaScript,具备庞大的社区支持和灵活性。两者各有优势,选择时需考虑团队技能和项目需求。
969 8

热门文章

最新文章