Fix Android 15 insets

This commit is contained in:
armv9 2025-03-03 20:06:43 +09:00
parent 151c110912
commit 914700d3d2
23 changed files with 97 additions and 102 deletions

View File

@ -25,7 +25,7 @@ import io.nekohasekai.sagernet.databinding.LayoutAboutBinding
import io.nekohasekai.sagernet.ktx.*
import io.nekohasekai.sagernet.plugin.PluginManager.loadString
import io.nekohasekai.sagernet.utils.PackageCache
import io.nekohasekai.sagernet.widget.ListHolderListener
import io.nekohasekai.sagernet.widget.ListListener
import libcore.Libcore
import moe.matsuri.nb4a.plugin.Plugins
@ -36,7 +36,7 @@ class AboutFragment : ToolbarFragment(R.layout.layout_about) {
val binding = LayoutAboutBinding.bind(view)
ViewCompat.setOnApplyWindowInsetsListener(view, ListHolderListener)
ViewCompat.setOnApplyWindowInsetsListener(view, ListListener)
toolbar.setTitle(R.string.menu_about)
parentFragmentManager.beginTransaction()

View File

@ -7,10 +7,15 @@ import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.util.SparseBooleanArray
import android.view.*
import android.view.KeyEvent
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.Filter
import android.widget.Filterable
import androidx.annotation.UiThread
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.util.contains
import androidx.core.util.set
import androidx.core.view.ViewCompat
@ -30,9 +35,12 @@ import io.nekohasekai.sagernet.SagerNet
import io.nekohasekai.sagernet.database.DataStore
import io.nekohasekai.sagernet.databinding.LayoutAppListBinding
import io.nekohasekai.sagernet.databinding.LayoutAppsItemBinding
import io.nekohasekai.sagernet.ktx.*
import io.nekohasekai.sagernet.ktx.crossFadeFrom
import io.nekohasekai.sagernet.ktx.launchCustomTab
import io.nekohasekai.sagernet.ktx.onMainDispatcher
import io.nekohasekai.sagernet.ktx.runOnDefaultDispatcher
import io.nekohasekai.sagernet.ktx.runOnIoDispatcher
import io.nekohasekai.sagernet.utils.PackageCache
import io.nekohasekai.sagernet.widget.ListHolderListener
import io.nekohasekai.sagernet.widget.ListListener
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
@ -79,7 +87,12 @@ class AppListActivity : ThemedActivity() {
binding.desc.text = "$packageName ($ver)"
//
binding.button.isVisible = true
binding.button.setImageDrawable(getDrawable(R.drawable.ic_baseline_info_24))
binding.button.setImageDrawable(
AppCompatResources.getDrawable(
this@AppListActivity,
R.drawable.ic_baseline_info_24
)
)
binding.button.setOnClickListener {
runOnIoDispatcher {
val jsi = NekoJSInterface(packageName)
@ -238,7 +251,6 @@ class AppListActivity : ThemedActivity() {
binding = LayoutAppListBinding.inflate(layoutInflater)
setContentView(binding.root)
ListHolderListener.setup(this)
setSupportActionBar(binding.toolbar)
supportActionBar?.apply {
setTitle(R.string.select_apps)

View File

@ -8,7 +8,11 @@ import android.graphics.drawable.Drawable
import android.os.Bundle
import android.text.TextUtils
import android.util.SparseBooleanArray
import android.view.*
import android.view.KeyEvent
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.Filter
import android.widget.Filterable
import androidx.annotation.UiThread
@ -35,7 +39,6 @@ import io.nekohasekai.sagernet.ktx.crossFadeFrom
import io.nekohasekai.sagernet.ktx.onMainDispatcher
import io.nekohasekai.sagernet.ktx.runOnDefaultDispatcher
import io.nekohasekai.sagernet.utils.PackageCache
import io.nekohasekai.sagernet.widget.ListHolderListener
import io.nekohasekai.sagernet.widget.ListListener
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
@ -191,7 +194,6 @@ class AppManagerActivity : ThemedActivity() {
binding = LayoutAppsBinding.inflate(layoutInflater)
setContentView(binding.root)
ListHolderListener.setup(this)
setSupportActionBar(binding.toolbar)
supportActionBar?.apply {
setTitle(R.string.proxied_apps)

View File

@ -23,7 +23,7 @@ import io.nekohasekai.sagernet.databinding.LayoutGroupItemBinding
import io.nekohasekai.sagernet.fmt.toUniversalLink
import io.nekohasekai.sagernet.group.GroupUpdater
import io.nekohasekai.sagernet.ktx.*
import io.nekohasekai.sagernet.widget.ListHolderListener
import io.nekohasekai.sagernet.widget.ListListener
import io.nekohasekai.sagernet.widget.QRCodeDialog
import io.nekohasekai.sagernet.widget.UndoSnackbarManager
import kotlinx.coroutines.delay
@ -45,7 +45,7 @@ class GroupFragment : ToolbarFragment(R.layout.layout_group),
super.onViewCreated(view, savedInstanceState)
activity = requireActivity() as MainActivity
ViewCompat.setOnApplyWindowInsetsListener(view, ListHolderListener)
ViewCompat.setOnApplyWindowInsetsListener(view, ListListener)
toolbar.setTitle(R.string.menu_group)
toolbar.inflateMenu(R.menu.add_group_menu)
toolbar.setOnMenuItemClickListener(this)

View File

@ -11,9 +11,11 @@ import android.view.MenuItem
import android.view.View
import android.widget.ScrollView
import androidx.appcompat.widget.Toolbar
import androidx.core.view.ViewCompat
import io.nekohasekai.sagernet.R
import io.nekohasekai.sagernet.databinding.LayoutLogcatBinding
import io.nekohasekai.sagernet.ktx.*
import io.nekohasekai.sagernet.widget.ListListener
import libcore.Libcore
import moe.matsuri.nb4a.utils.SendLog
@ -36,6 +38,8 @@ class LogcatFragment : ToolbarFragment(R.layout.layout_logcat),
binding.textview.breakStrategy = 0 // simple
}
ViewCompat.setOnApplyWindowInsetsListener(binding.root, ListListener)
reloadSession()
// TODO new logcat
}
@ -46,9 +50,11 @@ class LogcatFragment : ToolbarFragment(R.layout.layout_logcat),
line.contains("INFO[") || line.contains(" [Info]") -> {
color = ForegroundColorSpan((0xFF86C166).toInt())
}
line.contains("ERROR[") || line.contains(" [Error]") -> {
color = ForegroundColorSpan(Color.RED)
}
line.contains("WARN[") || line.contains(" [Warning]") -> {
color = ForegroundColorSpan(Color.RED)
}
@ -94,12 +100,14 @@ class LogcatFragment : ToolbarFragment(R.layout.layout_logcat),
}
}
R.id.action_send_logcat -> {
val context = requireContext()
runOnDefaultDispatcher {
SendLog.sendLog(context, "NB4A")
}
}
R.id.action_refresh -> {
reloadSession()
}

View File

@ -4,7 +4,6 @@ import android.Manifest.permission.POST_NOTIFICATIONS
import android.annotation.SuppressLint
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Color
import android.net.Uri
import android.os.Build
import android.os.Bundle
@ -15,18 +14,24 @@ import androidx.activity.addCallback
import androidx.annotation.IdRes
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import androidx.preference.PreferenceDataStore
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.navigation.NavigationView
import com.google.android.material.snackbar.Snackbar
import io.nekohasekai.sagernet.*
import io.nekohasekai.sagernet.GroupType
import io.nekohasekai.sagernet.Key
import io.nekohasekai.sagernet.R
import io.nekohasekai.sagernet.SagerNet
import io.nekohasekai.sagernet.aidl.ISagerNetService
import io.nekohasekai.sagernet.aidl.SpeedDisplayData
import io.nekohasekai.sagernet.aidl.TrafficData
import io.nekohasekai.sagernet.bg.BaseService
import io.nekohasekai.sagernet.bg.SagerConnection
import io.nekohasekai.sagernet.database.*
import io.nekohasekai.sagernet.database.DataStore
import io.nekohasekai.sagernet.database.GroupManager
import io.nekohasekai.sagernet.database.ProfileManager
import io.nekohasekai.sagernet.database.ProxyGroup
import io.nekohasekai.sagernet.database.SubscriptionBean
import io.nekohasekai.sagernet.database.preference.OnPreferenceDataStoreChangeListener
import io.nekohasekai.sagernet.databinding.LayoutMainBinding
import io.nekohasekai.sagernet.fmt.AbstractBean
@ -34,8 +39,13 @@ import io.nekohasekai.sagernet.fmt.KryoConverters
import io.nekohasekai.sagernet.fmt.PluginEntry
import io.nekohasekai.sagernet.group.GroupInterfaceAdapter
import io.nekohasekai.sagernet.group.GroupUpdater
import io.nekohasekai.sagernet.ktx.*
import io.nekohasekai.sagernet.widget.ListHolderListener
import io.nekohasekai.sagernet.ktx.alert
import io.nekohasekai.sagernet.ktx.isPlay
import io.nekohasekai.sagernet.ktx.launchCustomTab
import io.nekohasekai.sagernet.ktx.onMainDispatcher
import io.nekohasekai.sagernet.ktx.parseProxies
import io.nekohasekai.sagernet.ktx.readableMessage
import io.nekohasekai.sagernet.ktx.runOnDefaultDispatcher
import moe.matsuri.nb4a.utils.Util
class MainActivity : ThemedActivity(),
@ -49,10 +59,6 @@ class MainActivity : ThemedActivity(),
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
window?.apply {
statusBarColor = Color.TRANSPARENT
}
binding = LayoutMainBinding.inflate(layoutInflater)
binding.fab.initProgress(binding.fabProgress)
if (themeResId !in intArrayOf(
@ -86,7 +92,6 @@ class MainActivity : ThemedActivity(),
binding.stats.setOnClickListener { if (DataStore.serviceState.connected) binding.stats.testConnection() }
setContentView(binding.root)
ViewCompat.setOnApplyWindowInsetsListener(binding.coordinator, ListHolderListener)
changeState(BaseService.State.Idle)
connection.connect(this, this)
DataStore.configurationStore.registerChangeListener(this)

View File

@ -18,7 +18,7 @@ import io.nekohasekai.sagernet.database.SagerDatabase
import io.nekohasekai.sagernet.databinding.LayoutEmptyRouteBinding
import io.nekohasekai.sagernet.databinding.LayoutRouteItemBinding
import io.nekohasekai.sagernet.ktx.*
import io.nekohasekai.sagernet.widget.ListHolderListener
import io.nekohasekai.sagernet.widget.ListListener
import io.nekohasekai.sagernet.widget.UndoSnackbarManager
class RouteFragment : ToolbarFragment(R.layout.layout_route), Toolbar.OnMenuItemClickListener {
@ -33,7 +33,7 @@ class RouteFragment : ToolbarFragment(R.layout.layout_route), Toolbar.OnMenuItem
activity = requireActivity() as MainActivity
ViewCompat.setOnApplyWindowInsetsListener(view, ListHolderListener)
ViewCompat.setOnApplyWindowInsetsListener(view, ListListener)
toolbar.setTitle(R.string.menu_route)
toolbar.inflateMenu(R.menu.add_route_menu)
toolbar.setOnMenuItemClickListener(this)

View File

@ -26,7 +26,6 @@ import io.nekohasekai.sagernet.database.ProfileManager
import io.nekohasekai.sagernet.databinding.LayoutScannerBinding
import io.nekohasekai.sagernet.group.RawUpdater
import io.nekohasekai.sagernet.ktx.*
import io.nekohasekai.sagernet.widget.ListHolderListener
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger
@ -43,7 +42,6 @@ class ScannerActivity : ThemedActivity(),
if (Build.VERSION.SDK_INT >= 25) getSystemService<ShortcutManager>()!!.reportShortcutUsed("scan")
binding = LayoutScannerBinding.inflate(layoutInflater)
setContentView(binding.root)
ListHolderListener.setup(this)
setSupportActionBar(findViewById(R.id.toolbar))
supportActionBar?.apply {
setDisplayHomeAsUpEnabled(true)

View File

@ -4,14 +4,14 @@ import android.os.Bundle
import android.view.View
import androidx.core.view.ViewCompat
import io.nekohasekai.sagernet.R
import io.nekohasekai.sagernet.widget.ListHolderListener
import io.nekohasekai.sagernet.widget.ListListener
class SettingsFragment : ToolbarFragment(R.layout.layout_config_settings) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
ViewCompat.setOnApplyWindowInsetsListener(view, ListHolderListener)
ViewCompat.setOnApplyWindowInsetsListener(view, ListListener)
toolbar.setTitle(R.string.settings)
parentFragmentManager.beginTransaction()

View File

@ -1,6 +1,7 @@
package io.nekohasekai.sagernet.ui
import android.content.res.Configuration
import android.os.Build
import android.os.Bundle
import android.widget.TextView
import androidx.annotation.StringRes
@ -9,7 +10,7 @@ import androidx.core.app.ActivityCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import com.google.android.material.appbar.MaterialToolbar
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.snackbar.Snackbar
import io.nekohasekai.sagernet.R
import io.nekohasekai.sagernet.utils.Theme
@ -34,11 +35,16 @@ abstract class ThemedActivity : AppCompatActivity {
uiMode = resources.configuration.uiMode
findViewById<MaterialToolbar>(R.id.toolbar)?.let {
val appbarTopPadding = it.paddingTop
ViewCompat.setOnApplyWindowInsetsListener(it) { v, insets ->
v.updatePadding(top = appbarTopPadding + insets.getInsets(WindowInsetsCompat.Type.systemBars()).top)
if (Build.VERSION.SDK_INT >= 35) {
ViewCompat.setOnApplyWindowInsetsListener(findViewById(android.R.id.content)) { _, insets ->
val top = insets.getInsets(WindowInsetsCompat.Type.systemBars()).top
findViewById<AppBarLayout>(R.id.appbar)?.apply {
updatePadding(top = top)
// Logs.w("appbar $top")
}
// findViewById<NavigationView>(R.id.nav_view)?.apply {
// updatePadding(top = top)
// }
insets
}
}

View File

@ -6,6 +6,7 @@ import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.AlertDialog
import androidx.core.view.ViewCompat
import androidx.core.widget.addTextChangedListener
import com.blacksquircle.ui.editorkit.insert
import com.blacksquircle.ui.language.json.JsonLanguage
@ -18,6 +19,7 @@ import io.nekohasekai.sagernet.database.DataStore
import io.nekohasekai.sagernet.databinding.LayoutEditConfigBinding
import io.nekohasekai.sagernet.ktx.*
import io.nekohasekai.sagernet.ui.ThemedActivity
import io.nekohasekai.sagernet.widget.ListListener
import moe.matsuri.nb4a.ui.ExtendedKeyboard
import org.json.JSONObject
@ -97,6 +99,8 @@ class ConfigEditActivity : ThemedActivity() {
extendedKeyboard.setHasFixedSize(true)
extendedKeyboard.submitList("{},:_\"".map { it.toString() })
extendedKeyboard.setBackgroundColor(getColorAttr(R.attr.primaryOrTextPrimary))
ViewCompat.setOnApplyWindowInsetsListener(binding.root, ListListener)
}
fun formatText(): String? {

View File

@ -114,7 +114,7 @@ abstract class StandardV2RaySettingsActivity : ProfileSettingsActivity<StandardV
encryption.preference.apply {
this as SimpleMenuPreference
if (tmpBean!!.isVLESS) {
if (isVless) {
title = resources.getString(R.string.xtls_flow)
setIcon(R.drawable.ic_baseline_stream_24)
setEntries(R.array.xtls_flow_value)

View File

@ -1,37 +1,9 @@
package io.nekohasekai.sagernet.widget
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.core.graphics.Insets
import androidx.core.view.*
import io.nekohasekai.sagernet.R
object ListHolderListener : OnApplyWindowInsetsListener {
override fun onApplyWindowInsets(view: View, insets: WindowInsetsCompat): WindowInsetsCompat {
val statusBarInsets = insets.getInsets(WindowInsetsCompat.Type.statusBars())
view.setPadding(statusBarInsets.left,
statusBarInsets.top,
statusBarInsets.right,
statusBarInsets.bottom)
return WindowInsetsCompat.Builder(insets).apply {
setInsets(WindowInsetsCompat.Type.statusBars(), Insets.NONE)
/*setInsets(WindowInsetsCompat.Type.navigationBars(),
insets.getInsets(WindowInsetsCompat.Type.navigationBars()))*/
}.build()
}
fun setup(activity: AppCompatActivity) = activity.findViewById<View>(android.R.id.content).let {
ViewCompat.setOnApplyWindowInsetsListener(it, ListHolderListener)
WindowCompat.setDecorFitsSystemWindows(activity.window, false)
}
}
object MainListListener : OnApplyWindowInsetsListener {
override fun onApplyWindowInsets(view: View, insets: WindowInsetsCompat) = insets.apply {
view.updatePadding(bottom = view.resources.getDimensionPixelOffset(R.dimen.main_list_padding_bottom) +
insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom)
}
}
import androidx.core.view.OnApplyWindowInsetsListener
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
object ListListener : OnApplyWindowInsetsListener {
override fun onApplyWindowInsets(view: View, insets: WindowInsetsCompat) = insets.apply {

View File

@ -57,8 +57,7 @@
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/about_fragment_holder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true" />
android:layout_height="match_parent" />
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"

View File

@ -8,8 +8,10 @@
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:background="?attr/colorPrimary">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"

View File

@ -4,6 +4,7 @@
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp">
<com.google.android.material.appbar.MaterialToolbar

View File

@ -8,8 +8,10 @@
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:background="?attr/colorPrimary">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"

View File

@ -3,4 +3,4 @@
android:id="@+id/fragment_holder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true" />
/>

View File

@ -9,7 +9,10 @@
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/layout_appbar" />
<include
layout="@layout/layout_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
android:id="@+id/group_list"

View File

@ -1,19 +0,0 @@
<?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="match_parent"
android:orientation="vertical">
<include
layout="@layout/layout_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/fragment_holder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true" />
</LinearLayout>

View File

@ -5,21 +5,18 @@
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:fitsSystemWindows="true">
android:clipChildren="false">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/fragment_holder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true" />
android:layout_height="match_parent" />
<!-- We double trackThickness as half of it will be invisible -->
<com.google.android.material.progressindicator.CircularProgressIndicator
@ -51,7 +48,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:fitsSystemWindows="true"
android:nextFocusUp="@+id/fab"
app:backgroundTint="?colorMaterial300"
app:contentInsetStart="0dp"
@ -110,7 +106,6 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:itemIconTint="@color/navigation_icon"
app:itemTextColor="@color/navigation_icon"
app:menu="@menu/main_drawer_menu" />
@ -121,7 +116,6 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:itemIconTint="@color/navigation_icon"
app:itemShapeAppearance="@style/ShapeAppearance.MaterialComponents.MediumComponent"
app:itemShapeFillColor="@color/navigation_item"

View File

@ -9,7 +9,10 @@
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/layout_appbar" />
<include
layout="@layout/layout_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
android:id="@+id/route_list"

View File

@ -3,7 +3,10 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/layout_appbar" />
<include
layout="@layout/layout_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.camera.view.PreviewView
android:id="@+id/previewView"