Skip to content

Commit 0965bbf

Browse files
committed
Implement edge-to-edge UI for MainActivity
Upgrades the app to use an edge-to-edge immersive UI by updating the theme, layout, and MainActivity logic. Adds new Material theme, sets transparent system bars, handles window insets for gesture navigation, and ensures proper background blending to avoid black bars on older Android versions. Also updates dependencies and manifest for compatibility with targetSdkVersion 33 and Material Components.
1 parent 816976e commit 0965bbf

File tree

5 files changed

+165
-8
lines changed

5 files changed

+165
-8
lines changed

sample/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ android {
88
defaultConfig {
99
applicationId "com.github.aachartmodel.aainfographics.demo"
1010
minSdkVersion 19
11+
targetSdkVersion 33
1112
versionCode 1
1213
versionName "1.0.0"
1314
}
@@ -41,4 +42,5 @@ dependencies {
4142
implementation "androidx.constraintlayout:constraintlayout:2.1.4"
4243
implementation "androidx.coordinatorlayout:coordinatorlayout:1.2.0"
4344
implementation "com.google.code.gson:gson:2.10.1"
45+
implementation "com.google.android.material:material:1.9.0"
4446
}

sample/src/main/AndroidManifest.xml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,15 @@
99
android:label="@string/app_name"
1010
android:roundIcon="@mipmap/ic_launcher_round"
1111
android:supportsRtl="true"
12-
android:theme="@style/AppTheme"
12+
android:theme="@style/AppTheme.EdgeToEdge.Material"
1313
android:resizeableActivity="true"
1414
tools:ignore="AllowBackup">
15-
<activity android:name=".basiccontent.MainActivity">
15+
16+
<!-- 解决旧版系统(如 Android 8.x)可能出现的宽高比 letterboxing 黑边问题 -->
17+
<meta-data android:name="android.max_aspect" android:value="2.6" />
18+
19+
<activity android:name=".basiccontent.MainActivity"
20+
android:exported="true">
1621
<intent-filter>
1722
<action android:name="android.intent.action.MAIN" />
1823

sample/src/main/java/com/github/aachartmodel/aainfographics/demo/basiccontent/MainActivity.kt

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
11
package com.github.aachartmodel.aainfographics.demo.basiccontent
22
import android.content.Intent
3+
import android.os.Build
34
import android.os.Bundle
5+
import android.util.Log
6+
import android.view.View
7+
import android.view.WindowInsetsController
8+
import android.view.WindowManager
49
import android.widget.ExpandableListView
510
import android.widget.Toast
611
import androidx.appcompat.app.AppCompatActivity
12+
import androidx.core.view.ViewCompat
13+
import androidx.core.view.WindowCompat
14+
import androidx.core.view.WindowInsetsCompat
15+
import androidx.core.view.updatePadding
716
import com.github.aachartmodel.aainfographics.aachartcreator.AAChartType
817
import com.github.aachartmodel.aainfographics.demo.R
918
import com.github.aachartmodel.aainfographics.demo.additionalcontent.*
19+
import androidx.core.view.WindowInsetsControllerCompat
1020

1121
class MainActivity : AppCompatActivity() {
1222
private val chartTypeNameArr =
@@ -416,10 +426,90 @@ class MainActivity : AppCompatActivity() {
416426
override fun onCreate(savedInstanceState: Bundle?) {
417427
super.onCreate(savedInstanceState)
418428
setContentView(R.layout.activity_main)
429+
enableEdgeToEdgeUI()
430+
setupWindowInsets()
419431
setupExpandableListView()
420432
}
421433

422-
private fun setupExpandableListView() {
434+
private fun enableEdgeToEdgeUI() {
435+
WindowCompat.setDecorFitsSystemWindows(window, false)
436+
val white = android.graphics.Color.WHITE
437+
window.statusBarColor = android.graphics.Color.TRANSPARENT
438+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
439+
window.navigationBarColor = android.graphics.Color.TRANSPARENT
440+
}
441+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
442+
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
443+
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
444+
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
445+
}
446+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
447+
window.attributes.layoutInDisplayCutoutMode =
448+
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
449+
}
450+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
451+
window.isNavigationBarContrastEnforced = false
452+
window.isStatusBarContrastEnforced = false
453+
}
454+
val controller = WindowInsetsControllerCompat(window, window.decorView)
455+
controller.isAppearanceLightStatusBars = true
456+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
457+
controller.isAppearanceLightNavigationBars = true
458+
}
459+
// 为 R 以下版本补齐旧式 flag 以真正让内容延伸到导航栏后面
460+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
461+
@Suppress("DEPRECATION")
462+
window.decorView.systemUiVisibility = (
463+
View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
464+
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
465+
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
466+
)
467+
}
468+
}
469+
470+
private fun setupWindowInsets() {
471+
val rootView = findViewById<View>(android.R.id.content)
472+
val bottomSpacer = rootView.findViewById<View>(R.id.nav_inset_spacer)
473+
val listView = findViewById<ExpandableListView>(R.id.exlist_lol)
474+
rootView.setBackgroundColor(android.graphics.Color.WHITE)
475+
476+
ViewCompat.setOnApplyWindowInsetsListener(rootView) { _, insets ->
477+
val sysBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
478+
listView.updatePadding(top = sysBars.top)
479+
bottomSpacer?.let { spacer ->
480+
spacer.layoutParams = spacer.layoutParams.apply { height = sysBars.bottom }
481+
spacer.visibility = if (sysBars.bottom > 0) View.VISIBLE else View.GONE
482+
}
483+
listView.updatePadding(bottom = sysBars.bottom)
484+
adjustNavBarColorByMode(sysBars.bottom)
485+
Log.d("EdgeToEdge", "topInset=${sysBars.top}, bottomInset=${sysBars.bottom}")
486+
insets
487+
}
488+
}
489+
490+
private fun adjustNavBarColorByMode(bottomInset: Int) {
491+
// 粗略判断: 如果 bottomInset 很大(>= 80px) 说明是传统三键或导航条高度区域, 此时透明在部分 ROM 会退回黑色, 用白色与内容融合
492+
// 如果很小(0~40) 多半是手势导航, 可以保持透明达到真正边到边
493+
val isLikelyThreeButton = bottomInset >= 80
494+
if (isLikelyThreeButton) {
495+
// 使用与内容相同的白色, 避免设备强制绘制黑背景
496+
if (window.navigationBarColor != android.graphics.Color.WHITE) {
497+
window.navigationBarColor = android.graphics.Color.WHITE
498+
}
499+
} else {
500+
// 手势模式保持透明
501+
if (window.navigationBarColor != android.graphics.Color.TRANSPARENT && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
502+
window.navigationBarColor = android.graphics.Color.TRANSPARENT
503+
}
504+
}
505+
}
506+
507+
private fun setupExpandableListView() {
508+
val expandableListView = findViewById<ExpandableListView>(R.id.exlist_lol)
509+
510+
// 为ExpandableListView设置背景色,确保覆盖整个区域
511+
expandableListView.setBackgroundColor(android.graphics.Color.WHITE)
512+
423513
val groupTitleArr = arrayOf(
424514
"Basic Type Chart ---基础类型图表",
425515
"Special Type Chart ---特殊类型图表",
@@ -612,4 +702,5 @@ class MainActivity : AppCompatActivity() {
612702
companion object {
613703
private const val kChartTypeKey = "chartType"
614704
}
615-
}
705+
}
706+
Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,34 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
33
xmlns:tools="http://schemas.android.com/tools"
4+
xmlns:app="http://schemas.android.com/apk/res-auto"
45
android:layout_width="match_parent"
56
android:layout_height="match_parent"
7+
android:fitsSystemWindows="false"
8+
android:background="@android:color/white"
69
tools:context=".basiccontent.MainActivity">
710

811
<ExpandableListView
9-
android:id="@+id/exlist_lol"
10-
android:layout_width="match_parent"
11-
android:layout_height="match_parent"
12-
android:childDivider="#D5D5D5"/>
12+
android:id="@+id/exlist_lol"
13+
android:layout_width="0dp"
14+
android:layout_height="0dp"
15+
android:childDivider="#D5D5D5"
16+
android:clipToPadding="false"
17+
android:fitsSystemWindows="false"
18+
android:background="@android:color/white"
19+
app:layout_constraintTop_toTopOf="parent"
20+
app:layout_constraintBottom_toTopOf="@id/nav_inset_spacer"
21+
app:layout_constraintStart_toStartOf="parent"
22+
app:layout_constraintEnd_toEndOf="parent" />
23+
24+
<!-- 动态根据 WindowInsets 设置高度的底部占位 View,用来填充导航栏 / 手势栏区域背景,避免出现黑条 -->
25+
<View
26+
android:id="@+id/nav_inset_spacer"
27+
android:layout_width="0dp"
28+
android:layout_height="0dp"
29+
android:background="@android:color/white"
30+
app:layout_constraintBottom_toBottomOf="parent"
31+
app:layout_constraintStart_toStartOf="parent"
32+
app:layout_constraintEnd_toEndOf="parent" />
1333

1434
</androidx.constraintlayout.widget.ConstraintLayout>

sample/src/main/res/values/styles.xml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,43 @@
88
<item name="colorAccent">@color/colorAccent</item>
99
</style>
1010

11+
<!-- Edge-to-edge immersive theme (AppCompat) -->
12+
<style name="AppTheme.EdgeToEdge" parent="Theme.AppCompat.Light.NoActionBar">
13+
<item name="colorPrimary">@color/colorPrimary</item>
14+
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
15+
<item name="colorAccent">@color/colorAccent</item>
16+
<item name="android:windowTranslucentStatus">false</item>
17+
<item name="android:windowTranslucentNavigation">false</item>
18+
<item name="android:statusBarColor">@android:color/transparent</item>
19+
<item name="android:navigationBarColor">@android:color/transparent</item>
20+
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
21+
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
22+
<item name="android:windowLightStatusBar">true</item>
23+
<item name="android:windowLightNavigationBar">true</item>
24+
<item name="android:enforceStatusBarContrast">false</item>
25+
<item name="android:enforceNavigationBarContrast">false</item>
26+
<item name="android:fitsSystemWindows">false</item>
27+
<item name="android:navigationBarDividerColor">@android:color/transparent</item>
28+
</style>
29+
30+
<!-- MaterialComponents Edge-to-Edge theme -->
31+
<style name="AppTheme.EdgeToEdge.Material" parent="Theme.MaterialComponents.DayNight.NoActionBar">
32+
<item name="android:statusBarColor">@android:color/transparent</item>
33+
<item name="android:navigationBarColor">@android:color/transparent</item>
34+
<item name="android:navigationBarDividerColor">@android:color/transparent</item>
35+
<item name="android:enforceStatusBarContrast">false</item>
36+
<item name="android:enforceNavigationBarContrast">false</item>
37+
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
38+
<item name="android:windowTranslucentStatus">false</item>
39+
<item name="android:windowTranslucentNavigation">false</item>
40+
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
41+
<item name="android:windowLightStatusBar">true</item>
42+
<item name="android:windowLightNavigationBar">true</item>
43+
<!-- Material 颜色适配 -->
44+
<item name="colorPrimary">@color/colorPrimary</item>
45+
<item name="colorPrimaryVariant">@color/colorPrimaryDark</item>
46+
<item name="colorSecondary">@color/colorAccent</item>
47+
<item name="android:fitsSystemWindows">false</item>
48+
</style>
49+
1150
</resources>

0 commit comments

Comments
 (0)