├── app ├── .gitignore ├── src │ └── main │ │ ├── res │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── drawable │ │ │ ├── immersive_image.jpg │ │ │ └── ic_launcher_background.xml │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── values │ │ │ ├── strings.xml │ │ │ ├── colors.xml │ │ │ └── styles.xml │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ ├── layout │ │ │ ├── activity_dark_status_bar.xml │ │ │ ├── activity_immerse_image.xml │ │ │ ├── activity_main.xml │ │ │ └── activity_immersive_drawer.xml │ │ ├── menu │ │ │ └── menu_main.xml │ │ └── drawable-v24 │ │ │ └── ic_launcher_foreground.xml │ │ ├── java │ │ └── com │ │ │ └── drake │ │ │ └── statusbar │ │ │ └── sample │ │ │ ├── DarkStatusBarActivity.kt │ │ │ ├── ImmersiveImageActivity.kt │ │ │ ├── MainActivity.kt │ │ │ ├── ImmersiveDrawerActivity.kt │ │ │ └── BaseMenuActivity.kt │ │ └── AndroidManifest.xml ├── proguard-rules.pro └── build.gradle ├── statusbar ├── .gitignore ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ ├── res │ │ └── values │ │ │ └── strings.xml │ │ └── java │ │ └── com │ │ └── drake │ │ └── statusbar │ │ └── StatusBar.kt ├── build.gradle └── proguard-rules.pro ├── settings.gradle ├── signed ├── docs ├── img │ ├── preview.jpeg │ ├── code-preview.png │ ├── md │ │ └── light-status.png │ ├── book-open.svg │ ├── discussesions.svg │ └── issues.svg ├── other.md ├── font.md ├── image.md ├── index.md ├── css │ └── extra.css └── material │ └── partials │ └── footer.html ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── .github └── workflows │ └── main.yml ├── LICENSE ├── gradle.properties ├── mkdocs.yml ├── gradlew.bat ├── README.md └── gradlew /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /statusbar/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':statusbar' 2 | -------------------------------------------------------------------------------- /signed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/StatusBar/HEAD/signed -------------------------------------------------------------------------------- /statusbar/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/img/preview.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/StatusBar/HEAD/docs/img/preview.jpeg -------------------------------------------------------------------------------- /docs/img/code-preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/StatusBar/HEAD/docs/img/code-preview.png -------------------------------------------------------------------------------- /docs/img/md/light-status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/StatusBar/HEAD/docs/img/md/light-status.png -------------------------------------------------------------------------------- /statusbar/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Library 3 | 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/StatusBar/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/StatusBar/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/StatusBar/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/immersive_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/StatusBar/HEAD/app/src/main/res/drawable/immersive_image.jpg -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/StatusBar/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/StatusBar/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/StatusBar/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/StatusBar/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/StatusBar/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/StatusBar/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/navEditor.xml 5 | .DS_Store 6 | /build 7 | /captures 8 | .externalNativeBuild 9 | /.idea/ 10 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/StatusBar/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liangjingkanji/StatusBar/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | StatusBar 4 | 关闭抽屉 5 | 打开抽屉 6 | 7 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /docs/img/book-open.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | on: 3 | push: 4 | branches: 5 | - master 6 | jobs: 7 | deploy: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v2 11 | - uses: actions/setup-python@v2 12 | with: 13 | python-version: 3.x 14 | - run: pip install mkdocs-material 15 | - run: mkdocs gh-deploy --force 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/drake/statusbar/sample/DarkStatusBarActivity.kt: -------------------------------------------------------------------------------- 1 | package com.drake.statusbar.sample 2 | 3 | import com.drake.statusbar.darkMode 4 | import com.drake.statusbar.sample.databinding.ActivityDarkStatusBarBinding 5 | 6 | class DarkStatusBarActivity : BaseMenuActivity(R.layout.activity_dark_status_bar) { 7 | override fun initView() { 8 | darkMode() 9 | } 10 | } -------------------------------------------------------------------------------- /docs/other.md: -------------------------------------------------------------------------------- 1 | 2 | 所有函数都在`StatusBar`文件中 3 | 4 | 5 | 6 | 7 | 辅助函数 8 | 9 | | 函数 | 描述 | 10 | |-|-| 11 | | Activity.setNavigationBar | 显示导航栏 (系统开启可以隐藏, 系统未开启不能开启) | 12 | | Activity.setFullscreen | 显示全屏 | 13 | | Activity?.isNavigationBar | 是否存在导航栏 | 14 | | Context?.navigationBarHeight | 导航栏高度 | 15 | | Context?.statusBarHeight | 状态栏高度 | 16 | 17 | -------------------------------------------------------------------------------- /docs/font.md: -------------------------------------------------------------------------------- 1 | === "亮色模式" 2 | ```kotlin 3 | immersive(Color.YELLOW) 4 | ``` 5 | 6 | 7 | === "暗色模式" 8 | ```kotlin 9 | immersive(Color.YELLOW, true) 10 | ``` 11 | 12 | 13 | 14 | !!! note "使用View" 15 | `immersive`这个函数还可以传入View进去, 就会自动使用View的背景色作为状态栏颜色 16 | ```kotlin 17 | immersive(toolbar) 18 | ``` -------------------------------------------------------------------------------- /app/src/main/java/com/drake/statusbar/sample/ImmersiveImageActivity.kt: -------------------------------------------------------------------------------- 1 | package com.drake.statusbar.sample 2 | 3 | import com.drake.statusbar.immersive 4 | import com.drake.statusbar.sample.databinding.ActivityImmerseImageBinding 5 | import com.drake.statusbar.setActionBarTransparent 6 | 7 | class ImmersiveImageActivity : BaseMenuActivity(R.layout.activity_immerse_image) { 8 | override fun initView() { 9 | setActionBarTransparent() 10 | immersive() 11 | } 12 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_dark_status_bar.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | 12 | 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/drake/statusbar/sample/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.drake.statusbar.sample 2 | 3 | import com.drake.statusbar.immersive 4 | import com.drake.statusbar.sample.databinding.ActivityMainBinding 5 | 6 | class MainActivity : BaseMenuActivity(R.layout.activity_main) { 7 | 8 | override fun initView() { 9 | binding.toolbar.inflateMenu(R.menu.menu_main) 10 | binding.toolbar.setOnMenuItemClickListener { onOptionsItemSelected(it) } 11 | immersive(binding.toolbar) // or dark status bar 12 | // immersive(toolbar, true) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /docs/image.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 将图片作为状态栏背景 4 |
5 | 6 | ```kotlin 7 | immersive() 8 | ``` 9 | 10 | 11 | 12 | ## ActionBar 13 | 14 | ActionBar需要单独设置透明背景 15 | 16 | ```kotlin 17 | immersive() 18 | setActionBarTransparent() // 给ActionBar设置透明背景 19 | ``` 20 | 21 | 22 | 23 | ## Toolbar 24 | 25 | 需要为Toolbar设置状态栏上间距, 防止Toolbar被状态栏遮挡 26 | 27 | ```kotlin 28 | immersive() 29 | toolbar.statusPadding() // 指定PaddingTop(状态栏高度), 避免工具栏被状态栏遮挡 30 | ``` 31 |
32 | 33 | !!! success "防止状态栏遮挡" 34 | 任何View可以使用`statusPadding`方式防止遮挡 35 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_immerse_image.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 11 | 12 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | 一行代码创建透明状态栏 2 | 3 | 1. 状态栏颜色指的状态栏背景色 4 | 1. 状态栏文字颜色白色(即亮色模式), 可以设成黑色(暗色模式) 5 | 6 | === "亮色模式" 7 | 8 | ```kotlin 9 | immersive(toolbar) 10 | ``` 11 | 12 | === "暗色模式" 13 | 14 | ```kotlin 15 | immersive(toolbar, true) // 第二个参数即指定状态栏文字颜色为暗色模式 16 | ``` 17 | 18 | | 函数 | 描述 | 19 | |-|-| 20 | | Activity.`statusBarColor` | 指定状态栏颜色 | 21 | | Activity.`immersive` | 指定透明状态栏或状态栏颜色 | 22 | | Activity.`immersiveExit` | 退出沉浸式状态栏并恢复默认状态栏 | 23 | | Activity.`darkMode` | 指定状态栏文字颜色为暗色模式 | 24 | | View.`statusPadding` | 为View指定上内间距(为状态栏高度) | 25 | | Activity.`setActionBarBackground` | 指定ActionBar背景颜色, 如果存在 | -------------------------------------------------------------------------------- /statusbar/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | 4 | android { 5 | compileSdkVersion 29 6 | defaultConfig { 7 | minSdkVersion 16 8 | targetSdkVersion 29 9 | versionCode 1 10 | versionName "1.0" 11 | 12 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 13 | } 14 | 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | 22 | } 23 | 24 | dependencies { 25 | implementation fileTree(dir: 'libs', include: ['*.jar']) 26 | implementation 'androidx.appcompat:appcompat:1.1.0' 27 | } 28 | repositories { 29 | mavenCentral() 30 | } 31 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /statusbar/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 12 | 13 | 20 | 21 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 劉強東 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 12 | 13 | 21 | 22 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/drake/statusbar/sample/ImmersiveDrawerActivity.kt: -------------------------------------------------------------------------------- 1 | package com.drake.statusbar.sample 2 | 3 | import androidx.appcompat.app.ActionBarDrawerToggle 4 | import com.drake.statusbar.immersive 5 | import com.drake.statusbar.sample.databinding.ActivityImmersiveDrawerBinding 6 | import com.drake.statusbar.statusPadding 7 | 8 | class ImmersiveDrawerActivity : BaseMenuActivity(R.layout.activity_immersive_drawer) { 9 | override fun initView() { 10 | val toggle = ActionBarDrawerToggle( 11 | this, 12 | binding.drawer, 13 | binding.toolbar, 14 | R.string.open_drawer, 15 | R.string.close_drawer 16 | ) 17 | binding.drawer.addDrawerListener(toggle) 18 | toggle.syncState() 19 | 20 | // 使抽屉展开后是半透明状态栏 21 | immersive() 22 | binding.toolbar.statusPadding() 23 | 24 | // 以下属于全透明状态栏方案 25 | // immersive() 26 | // toolbar.statusPadding() 27 | 28 | // 如果不需要抽屉展开后是半透明状态栏直接设置以下即可, 以下属于设置状态栏颜色方案 29 | // immersive(toolbar) 30 | 31 | binding.toolbar.inflateMenu(R.menu.menu_main) 32 | binding.toolbar.setOnMenuItemClickListener { onOptionsItemSelected(it) } 33 | } 34 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 16 | 19 | 22 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2018 Drake, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | org.gradle.jvmargs=-Xmx1536m 17 | # When configured, Gradle will run in incubating parallel mode. 18 | # This option should only be used with decoupled projects. More details, visit 19 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 20 | # org.gradle.parallel=true 21 | # AndroidX package structure to make it clearer which packages are bundled with the 22 | # Android operating system, and which are packaged with your app's APK 23 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 24 | android.useAndroidX=true 25 | # Automatically convert third-party libraries to use AndroidX 26 | android.enableJetifier=true 27 | # Kotlin code style for this project: "official" or "obsolete": 28 | kotlin.code.style=official 29 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_immersive_drawer.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 12 | 13 | 16 | 17 | 25 | 26 | 27 | 28 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /docs/img/discussesions.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 编组备份 5 | 6 | 7 | 8 | 11 | 14 | 16 | 讨论 17 | 18 | 20 | Discussions 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /docs/img/issues.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 编组 5 | 6 | 7 | 8 | 9 | 12 | 14 | 常见问题 15 | 16 | 17 | 18 | 21 | 23 | Issues 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/drake/statusbar/sample/BaseMenuActivity.kt: -------------------------------------------------------------------------------- 1 | package com.drake.statusbar.sample 2 | 3 | import android.content.Intent 4 | import android.view.Menu 5 | import android.view.MenuItem 6 | import androidx.annotation.LayoutRes 7 | import androidx.databinding.ViewDataBinding 8 | import com.drake.engine.base.EngineActivity 9 | 10 | open class BaseMenuActivity(@LayoutRes contentLayoutId: Int = 0) : EngineActivity(contentLayoutId) { 11 | override fun initView() { 12 | } 13 | 14 | override fun initData() { 15 | } 16 | 17 | override fun onCreateOptionsMenu(menu: Menu?): Boolean { 18 | menuInflater.inflate(R.menu.menu_main, menu) 19 | return super.onCreateOptionsMenu(menu) 20 | } 21 | 22 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 23 | when (item.itemId) { 24 | R.id.immersiveDrawerActivity -> startActivity( 25 | Intent( 26 | this, 27 | ImmersiveDrawerActivity::class.java 28 | ) 29 | ) 30 | 31 | R.id.immersiveImageActivity -> startActivity( 32 | Intent( 33 | this, 34 | ImmersiveImageActivity::class.java 35 | ) 36 | ) 37 | 38 | R.id.darkStatusBarActivity -> startActivity( 39 | Intent( 40 | this, 41 | DarkStatusBarActivity::class.java 42 | ) 43 | ) 44 | 45 | R.id.mainActivity -> startActivity(Intent(this, MainActivity::class.java)) 46 | } 47 | finish() 48 | return super.onOptionsItemSelected(item) 49 | } 50 | } -------------------------------------------------------------------------------- /docs/css/extra.css: -------------------------------------------------------------------------------- 1 | @font-face{ 2 | font-family: 'Iosevka Curly'; 3 | src: local('Iosevka Curly Medium'), 4 | url('https://raw.githubusercontent.com/liangjingkanji/liangjingkanji/master/font/iosevka-curly/iosevka-curly-medium.woff2') format('woff2'); 5 | font-display: swap; 6 | font-weight: normal; 7 | font-style: normal; 8 | } 9 | @font-face{ 10 | font-family: 'Iosevka Curly'; 11 | src: local('Iosevka Curly Bold'), 12 | url('https://raw.githubusercontent.com/liangjingkanji/liangjingkanji/master/font/iosevka-curly/iosevka-curly-bold.woff2') format('woff2'); 13 | font-display: swap; 14 | font-weight: bold; 15 | font-style: normal; 16 | } 17 | @font-face{ 18 | font-family: 'HYYouYuan'; 19 | src: local('HYYouYuan-55W'), 20 | url('https://raw.githubusercontent.com/liangjingkanji/liangjingkanji/master/font/HYYouYuan/HYYouYuan-55W.ttf') format('truetype'); 21 | font-display: swap; 22 | font-weight: normal; 23 | font-style: normal; 24 | } 25 | @font-face{ 26 | font-family: 'HYYouYuan'; 27 | src: local('HYYouYuan-75W'), 28 | url('https://raw.githubusercontent.com/liangjingkanji/liangjingkanji/master/font/HYYouYuan/HYYouYuan-75W.ttf') format('truetype'); 29 | font-display: swap; 30 | font-weight: bold; 31 | font-style: normal; 32 | } 33 | 34 | * { 35 | -webkit-font-feature-settings: "liga" on, "calt" on; 36 | -webkit-font-smoothing: subpixel-antialiased; 37 | -moz-osx-font-smoothing: auto; 38 | text-rendering: optimizeLegibility; 39 | font-family: "Iosevka Curly", HYYouYuan !important; 40 | } 41 | 42 | code, 43 | .md-nav, 44 | .md-typeset code, 45 | .md-typeset { 46 | font-size: 14px !important; 47 | } 48 | 49 | .highlight span.filename, 50 | .md-typeset .admonition-title, 51 | .md-typeset summary { 52 | font-weight: normal; 53 | } -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-kapt' 3 | apply plugin: 'kotlin-android' 4 | 5 | android { 6 | compileSdkVersion 33 7 | 8 | signingConfigs { 9 | signed { 10 | storeFile file("../signed") 11 | storePassword "s73dfyUxkjuq" 12 | keyAlias "key0" 13 | keyPassword "s73dfyUxkjuq" 14 | } 15 | } 16 | defaultConfig { 17 | applicationId "com.drake.statusbar.sample" 18 | minSdkVersion 19 19 | targetSdkVersion 33 20 | versionCode 1 21 | versionName "1.0" 22 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 23 | signingConfig signingConfigs.signed 24 | } 25 | 26 | buildFeatures.dataBinding = true 27 | 28 | buildTypes { 29 | release { 30 | minifyEnabled false 31 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 32 | } 33 | } 34 | compileOptions { 35 | targetCompatibility JavaVersion.VERSION_11 36 | sourceCompatibility JavaVersion.VERSION_11 37 | } 38 | 39 | applicationVariants.all { 40 | it.outputs.each { output -> 41 | output.outputFileName = "StatusBar.apk" 42 | } 43 | } 44 | } 45 | 46 | dependencies { 47 | implementation fileTree(dir: 'libs', include: ['*.jar']) 48 | implementation 'androidx.appcompat:appcompat:1.6.1' 49 | implementation 'androidx.core:core-ktx:1.10.1' 50 | implementation 'androidx.constraintlayout:constraintlayout:2.1.4' 51 | implementation 'com.google.android.material:material:1.9.0' 52 | implementation project(path: ':statusbar') 53 | 54 | implementation 'com.github.liangjingkanji:Engine:0.0.74' 55 | implementation 'com.github.liangjingkanji:debugkit:1.3.0' 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 13 | 14 | 20 | 23 | 26 | 27 | 28 | 29 | 35 | 36 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: StatusBar 2 | site_description: StatusBar document 3 | repo_url: https://github.com/liangjingkanji/StatusBar 4 | extra: 5 | social: 6 | - icon: fontawesome/brands/github 7 | link: https://github.com/liangjingkanji 8 | - icon: fontawesome/brands/qq 9 | link: https://raw.githubusercontent.com/liangjingkanji/liangjingkanji/master/img/group-qrcode.png 10 | 11 | site_author: 劉強東 12 | copyright: Copyright © 2018 - 2023 劉強東 13 | repo_name: GitHub 14 | docs_dir: 'docs' 15 | extra_css: 16 | - css/extra.css 17 | theme: 18 | name: material 19 | custom_dir: docs/material 20 | favicon: img/book-open.svg 21 | logo: img/book-open.svg 22 | palette: 23 | - media: "(prefers-color-scheme: light)" 24 | scheme: default 25 | primary: white 26 | font: false 27 | language: zh 28 | features: 29 | - navigation.top 30 | - navigation.prune 31 | - navigation.footer 32 | - navigation.instant 33 | - search.highlight 34 | - search.suggest 35 | - search.share 36 | - content.code.copy 37 | - content.code.annotate 38 | plugins: 39 | - offline 40 | - search: 41 | separator: '[\s\-,:!=\[\]()"/]+|(?!\b)(?=[A-Z][a-z])|\.(?!\d)|&[lg]t;' 42 | lang: 43 | - en 44 | - zh 45 | markdown_extensions: 46 | - toc: 47 | permalink: true 48 | - pymdownx.tasklist: 49 | custom_checkbox: true 50 | - pymdownx.tabbed: 51 | alternate_style: true 52 | - pymdownx.highlight: 53 | anchor_linenums: true 54 | line_spans: __span 55 | pygments_lang_class: true 56 | - pymdownx.inlinehilite 57 | - pymdownx.snippets 58 | - pymdownx.superfences 59 | - attr_list 60 | - def_list 61 | - md_in_html 62 | - admonition 63 | - pymdownx.highlight 64 | - pymdownx.details 65 | - pymdownx.caret 66 | - pymdownx.keys 67 | - pymdownx.mark 68 | - pymdownx.tilde 69 | - pymdownx.emoji: 70 | emoji_index: !!python/name:materialx.emoji.twemoji 71 | emoji_generator: !!python/name:materialx.emoji.to_svg 72 | 73 | nav: 74 | - 通用透明状态栏: 'index.md' 75 | - 图片透明状态栏: 'image.md' 76 | - 状态栏字体颜色: 'font.md' 77 | - 其他: 'other.md' -------------------------------------------------------------------------------- /docs/material/partials/footer.html: -------------------------------------------------------------------------------- 1 | {% import "partials/language.html" as lang with context %} 2 | 3 | 4 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## StatusBar 2 | 3 |

4 | 5 |

一行代码的透明状态栏

6 | 7 |

8 | 使用文档 9 | | 无法访问? 10 | | 下载体验 11 |

12 | 13 |

14 | 15 |

16 | 17 | 18 | 19 | 20 |

21 | 22 | ### 特点 23 | 24 | - [x] 学习成本低 25 | - [x] 启用/关闭透明状态栏 26 | - [x] 状态栏背景/文字颜色 27 | - [x] 状态栏/导航栏高度 28 | - [x] 为View设置指定状态栏高度的Padding/Margin 29 | - [x] 支持Activity/Fragment/DrawerLayout 30 | 31 | 32 |
33 | 34 | ## 安装 35 | 36 | Project 的 settings.gradle 添加仓库 37 | 38 | ```kotlin 39 | dependencyResolutionManagement { 40 | repositories { 41 | // ... 42 | maven { url 'https://jitpack.io' } 43 | } 44 | } 45 | ``` 46 | 47 | Module 的 build.gradle 添加依赖框架 48 | 49 | ```groovy 50 | implementation 'com.github.liangjingkanji:StatusBar:2.0.5' 51 | ``` 52 | 53 |
54 | 55 | ## License 56 | 57 | ``` 58 | MIT License 59 | 60 | Copyright (c) 2023 劉強東 https://github.com/liangjingkanji 61 | 62 | Permission is hereby granted, free of charge, to any person obtaining a copy 63 | of this software and associated documentation files (the "Software"), to deal 64 | in the Software without restriction, including without limitation the rights 65 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 66 | copies of the Software, and to permit persons to whom the Software is 67 | furnished to do so, subject to the following conditions: 68 | 69 | The above copyright notice and this permission notice shall be included in all 70 | copies or substantial portions of the Software. 71 | 72 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 73 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 74 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 75 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 76 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 77 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 78 | SOFTWARE. 79 | ``` 80 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /statusbar/src/main/java/com/drake/statusbar/StatusBar.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 劉強東 https://github.com/liangjingkanji 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | package com.drake.statusbar 26 | 27 | import android.annotation.SuppressLint 28 | import android.app.Activity 29 | import android.content.Context 30 | import android.content.res.Resources 31 | import android.graphics.Color 32 | import android.graphics.drawable.ColorDrawable 33 | import android.os.Build 34 | import android.util.TypedValue 35 | import android.view.View 36 | import android.view.ViewGroup 37 | import android.view.WindowManager 38 | import android.widget.RelativeLayout 39 | import androidx.annotation.ColorInt 40 | import androidx.annotation.ColorRes 41 | import androidx.appcompat.app.AppCompatActivity 42 | 43 | private const val COLOR_TRANSPARENT = 0 44 | 45 | // 46 | /** 设置状态栏颜色 */ 47 | fun Activity.statusBarColor(@ColorInt color: Int) { 48 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 49 | window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) 50 | window?.statusBarColor = color 51 | } 52 | } 53 | 54 | /** 设置状态栏颜色 */ 55 | fun Activity.statusBarColorRes(@ColorRes colorRes: Int) = statusBarColor(resources.getColor(colorRes)) 56 | 57 | // 58 | 59 | 60 | // 61 | /** 62 | * 使用视图的背景色作为状态栏颜色 63 | * @param v 提取该View的背景颜色设置为状态栏颜色, 如果该View没有背景颜色则该函数调用无效 64 | * @param darkMode 是否显示暗色状态栏文字颜色 65 | */ 66 | @JvmOverloads 67 | fun Activity.immersive(v: View, darkMode: Boolean? = null) { 68 | val background = v.background 69 | if (background is ColorDrawable) { 70 | immersive(background.color, darkMode) 71 | } 72 | } 73 | 74 | /** 75 | * 设置透明状态栏或者状态栏颜色, 此函数会导致状态栏覆盖界面, 76 | * 如果不希望被状态栏遮挡Toolbar请再调用[statusPadding]设置视图的paddingTop 或者 [statusMargin]设置视图的marginTop为状态栏高度 77 | * 78 | * 如果不指定状态栏颜色则会应用透明状态栏(全屏属性), 会导致键盘遮挡输入框 79 | * 80 | * @param color 状态栏颜色, 不指定则为透明状态栏 81 | * @param darkMode 是否显示暗色状态栏文字颜色 82 | */ 83 | @SuppressLint("ObsoleteSdkInt") 84 | @JvmOverloads 85 | fun Activity.immersive(@ColorInt color: Int = COLOR_TRANSPARENT, darkMode: Boolean? = null) { 86 | when { 87 | Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> { 88 | when (color) { 89 | COLOR_TRANSPARENT -> { 90 | window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) 91 | window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) 92 | window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE) 93 | window.statusBarColor = color 94 | } 95 | else -> { 96 | window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) 97 | window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) 98 | window.statusBarColor = color 99 | } 100 | } 101 | } 102 | Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT -> { 103 | window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) 104 | if (color != COLOR_TRANSPARENT) { 105 | setTranslucentView(window.decorView as ViewGroup, color) 106 | } 107 | } 108 | } 109 | if (darkMode != null) { 110 | darkMode(darkMode) 111 | } 112 | } 113 | 114 | /** 115 | * 退出沉浸式状态栏并恢复默认状态栏颜色 116 | * 117 | * @param black 是否显示黑色状态栏白色文字(不恢复状态栏颜色) 118 | */ 119 | @JvmOverloads 120 | fun Activity.immersiveExit(black: Boolean = false) { 121 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 122 | window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) 123 | window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE 124 | and View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) 125 | 126 | // 恢复默认状态栏颜色 127 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 128 | if (black) { 129 | window.clearFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) 130 | } else { 131 | val typedArray = obtainStyledAttributes(intArrayOf(android.R.attr.statusBarColor)) 132 | window.statusBarColor = typedArray.getColor(0, 0) 133 | typedArray.recycle() 134 | } 135 | } 136 | } 137 | } 138 | 139 | /** 140 | * 获取颜色资源值来设置状态栏 141 | */ 142 | @JvmOverloads 143 | fun Activity.immersiveRes(@ColorRes color: Int, darkMode: Boolean? = null) = 144 | immersive(resources.getColor(color), darkMode) 145 | 146 | // 147 | 148 | 149 | // 150 | 151 | 152 | /** 153 | * 开关状态栏暗色模式, 并不会透明状态栏, 只是单纯的状态栏文字变暗色调. 154 | * 155 | * @param darkMode 状态栏文字是否为暗色 156 | */ 157 | @JvmOverloads 158 | fun Activity.darkMode(darkMode: Boolean = true) { 159 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 160 | var systemUiVisibility = window.decorView.systemUiVisibility 161 | systemUiVisibility = if (darkMode) { 162 | systemUiVisibility or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR 163 | } else { 164 | systemUiVisibility and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv() 165 | } 166 | window.decorView.systemUiVisibility = systemUiVisibility 167 | } 168 | } 169 | 170 | // 171 | 172 | // 173 | 174 | /** 175 | * 增加View的paddingTop, 增加高度为状态栏高度, 用于防止视图和状态栏重叠 176 | * 如果是RelativeLayout设置padding值会导致centerInParent等属性无法正常显示 177 | * @param remove 如果默认paddingTop大于状态栏高度则添加无效, 如果小于状态栏高度则无法删除 178 | */ 179 | @JvmOverloads 180 | fun View.statusPadding(remove: Boolean = false) { 181 | if (this is RelativeLayout) { 182 | throw UnsupportedOperationException("Unsupported set statusPadding for RelativeLayout") 183 | } 184 | if (Build.VERSION.SDK_INT >= 19) { 185 | val statusBarHeight = context.statusBarHeight 186 | val lp = layoutParams 187 | if (lp != null && lp.height > 0) { 188 | lp.height += statusBarHeight //增高 189 | } 190 | if (remove) { 191 | if (paddingTop < statusBarHeight) return 192 | setPadding( 193 | paddingLeft, paddingTop - statusBarHeight, 194 | paddingRight, paddingBottom 195 | ) 196 | } else { 197 | if (paddingTop >= statusBarHeight) return 198 | setPadding( 199 | paddingLeft, paddingTop + statusBarHeight, 200 | paddingRight, paddingBottom 201 | ) 202 | } 203 | } 204 | } 205 | 206 | /** 207 | * 增加View的marginTop值, 增加高度为状态栏高度, 用于防止视图和状态栏重叠 208 | * @param remove 如果默认marginTop大于状态栏高度则添加无效, 如果小于状态栏高度则无法删除 209 | */ 210 | @JvmOverloads 211 | fun View.statusMargin(remove: Boolean = false) { 212 | if (Build.VERSION.SDK_INT >= 19) { 213 | val statusBarHeight = context.statusBarHeight 214 | val lp = layoutParams as ViewGroup.MarginLayoutParams 215 | if (remove) { 216 | if (lp.topMargin < statusBarHeight) return 217 | lp.topMargin -= statusBarHeight 218 | layoutParams = lp 219 | } else { 220 | if (lp.topMargin >= statusBarHeight) return 221 | lp.topMargin += statusBarHeight 222 | layoutParams = lp 223 | } 224 | } 225 | } 226 | 227 | 228 | /** 229 | * 创建假的透明栏 230 | */ 231 | private fun Context.setTranslucentView(container: ViewGroup, color: Int) { 232 | if (Build.VERSION.SDK_INT >= 19) { 233 | var simulateStatusBar: View? = container.findViewById(android.R.id.custom) 234 | if (simulateStatusBar == null && color != 0) { 235 | simulateStatusBar = View(container.context) 236 | simulateStatusBar.id = android.R.id.custom 237 | val lp = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, statusBarHeight) 238 | container.addView(simulateStatusBar, lp) 239 | } 240 | simulateStatusBar?.setBackgroundColor(color) 241 | } 242 | } 243 | 244 | // 245 | 246 | // 247 | 248 | /** 249 | * 设置ActionBar的背景颜色 250 | */ 251 | fun AppCompatActivity.setActionBarBackground(@ColorInt color: Int) { 252 | supportActionBar?.setBackgroundDrawable(ColorDrawable(color)) 253 | } 254 | 255 | fun AppCompatActivity.setActionBarBackgroundRes(@ColorRes color: Int) { 256 | supportActionBar?.setBackgroundDrawable(ColorDrawable(resources.getColor(color))) 257 | } 258 | 259 | /** 260 | * 设置ActionBar的背景颜色为透明 261 | */ 262 | fun AppCompatActivity.setActionBarTransparent() { 263 | supportActionBar?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) 264 | } 265 | // 266 | 267 | // 268 | 269 | /** 270 | * 显示或隐藏导航栏, 系统开启可以隐藏, 系统未开启不能开启 271 | * 272 | * @param enabled 是否显示导航栏 273 | */ 274 | @JvmOverloads 275 | fun Activity.setNavigationBar(enabled: Boolean = true) { 276 | if (Build.VERSION.SDK_INT in 12..18) { 277 | if (enabled) { 278 | window.decorView.systemUiVisibility = View.VISIBLE 279 | } else { 280 | window.decorView.systemUiVisibility = View.GONE 281 | } 282 | } else if (Build.VERSION.SDK_INT >= 19) { 283 | val systemUiVisibility = window.decorView.systemUiVisibility 284 | if (enabled) { 285 | window.decorView.systemUiVisibility = 286 | systemUiVisibility and View.SYSTEM_UI_FLAG_HIDE_NAVIGATION and View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY 287 | } else { 288 | window.decorView.systemUiVisibility = systemUiVisibility or 289 | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY 290 | } 291 | } 292 | } 293 | 294 | /** 295 | * 设置是否全屏 296 | * 297 | * @param enabled 是否全屏显示 298 | */ 299 | @JvmOverloads 300 | fun Activity.setFullscreen(enabled: Boolean = true) { 301 | val systemUiVisibility = window.decorView.systemUiVisibility 302 | window.decorView.systemUiVisibility = if (enabled) { 303 | systemUiVisibility or View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE 304 | } else { 305 | systemUiVisibility or View.SYSTEM_UI_FLAG_LAYOUT_STABLE and View.SYSTEM_UI_FLAG_FULLSCREEN.inv() 306 | } 307 | } 308 | 309 | /** 310 | * 是否有导航栏 311 | */ 312 | val Activity?.isNavigationBar: Boolean 313 | get() { 314 | this ?: return false 315 | val vp = window.decorView as? ViewGroup 316 | if (vp != null) { 317 | for (i in 0 until vp.childCount) { 318 | vp.getChildAt(i).context.packageName 319 | if (vp.getChildAt(i).id != -1 && "navigationBarBackground" == 320 | resources.getResourceEntryName(vp.getChildAt(i).id) 321 | ) return true 322 | } 323 | } 324 | return false 325 | } 326 | 327 | /** 328 | * 如果当前设备存在导航栏返回导航栏高度, 否则0 329 | */ 330 | val Context?.navigationBarHeight: Int 331 | get() { 332 | this ?: return 0 333 | val resourceId: Int = resources.getIdentifier("navigation_bar_height", "dimen", "android") 334 | var height = 0 335 | if (resourceId > 0) { 336 | height = resources.getDimensionPixelSize(resourceId) 337 | } 338 | return height 339 | } 340 | 341 | 342 | /** 343 | * 状态栏高度 344 | */ 345 | val Context?.statusBarHeight: Int 346 | get() { 347 | this ?: return 0 348 | var result = 24 349 | val resId = resources.getIdentifier("status_bar_height", "dimen", "android") 350 | result = if (resId > 0) { 351 | resources.getDimensionPixelSize(resId) 352 | } else { 353 | TypedValue.applyDimension( 354 | TypedValue.COMPLEX_UNIT_DIP, 355 | result.toFloat(), Resources.getSystem().displayMetrics 356 | ).toInt() 357 | } 358 | return result 359 | } 360 | // 361 | --------------------------------------------------------------------------------