Aperture: Rework settings
More generic, fixed padding highlight, improved app bar layout
Change-Id: I2beeb5f3bcd119f2e40ba3cfd7fcf9521b5679ea
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d32f1e0..e74bedd 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -153,7 +153,7 @@
android:configChanges="orientation|screenLayout|screenSize|smallestScreenSize|keyboardHidden"
android:exported="false"
android:label="@string/title_activity_settings"
- android:theme="@style/Theme.Aperture.Settings" />
+ android:theme="@style/Theme.SettingsLib" />
</application>
diff --git a/app/src/main/java/org/lineageos/aperture/SettingsActivity.kt b/app/src/main/java/org/lineageos/aperture/SettingsActivity.kt
index 967a5e6..5815491 100644
--- a/app/src/main/java/org/lineageos/aperture/SettingsActivity.kt
+++ b/app/src/main/java/org/lineageos/aperture/SettingsActivity.kt
@@ -5,8 +5,6 @@
package org.lineageos.aperture
-import android.graphics.Color
-import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.MenuItem
@@ -14,25 +12,37 @@
import android.view.ViewGroup
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
+import androidx.annotation.CallSuper
+import androidx.annotation.Px
+import androidx.annotation.XmlRes
import androidx.appcompat.app.AppCompatActivity
+import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
-import androidx.core.view.updateLayoutParams
+import androidx.core.view.updatePadding
import androidx.preference.ListPreference
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreference
+import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.appbar.MaterialToolbar
+import org.lineageos.aperture.ext.setOffset
import org.lineageos.aperture.utils.CameraSoundsUtils
import org.lineageos.aperture.utils.PermissionsUtils
+import kotlin.reflect.safeCast
class SettingsActivity : AppCompatActivity(R.layout.activity_settings) {
+ private val appBarLayout by lazy { findViewById<AppBarLayout>(R.id.appBarLayout) }
+ private val coordinatorLayout by lazy { findViewById<CoordinatorLayout>(R.id.coordinatorLayout) }
private val toolbar by lazy { findViewById<MaterialToolbar>(R.id.toolbar) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+ // Setup edge-to-edge
+ WindowCompat.setDecorFitsSystemWindows(window, false)
+
if (savedInstanceState == null) {
supportFragmentManager
.beginTransaction()
@@ -40,8 +50,6 @@
.commit()
}
- WindowCompat.setDecorFitsSystemWindows(window, false)
-
setSupportActionBar(toolbar)
supportActionBar?.apply {
setDisplayHomeAsUpEnabled(true)
@@ -60,38 +68,76 @@
}
}
- abstract class SettingsFragment : PreferenceFragmentCompat() {
+ abstract class SettingsFragment(
+ @XmlRes private val preferencesResId: Int,
+ ) : PreferenceFragmentCompat() {
+ private val settingsActivity
+ get() = SettingsActivity::class.safeCast(activity)
+
+ @Px
+ private var appBarOffset = -1
+
+ private val offsetChangedListener = AppBarLayout.OnOffsetChangedListener { _, i ->
+ appBarOffset = -i
+ }
+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- setDivider(ColorDrawable(Color.TRANSPARENT))
- setDividerHeight(0)
+ settingsActivity?.let { settingsActivity ->
+ val appBarLayout = settingsActivity.appBarLayout
- listView?.let {
- ViewCompat.setOnApplyWindowInsetsListener(it) { _, windowInsets ->
- val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
-
- it.updateLayoutParams<ViewGroup.MarginLayoutParams> {
- bottomMargin = insets.bottom
- leftMargin = insets.left
- rightMargin = insets.right
- }
-
- windowInsets
+ if (appBarOffset != -1) {
+ appBarLayout.setOffset(appBarOffset, settingsActivity.coordinatorLayout)
+ } else {
+ appBarLayout.setExpanded(true, false)
}
+
+ appBarLayout.setLiftOnScrollTargetView(listView)
+
+ appBarLayout.addOnOffsetChangedListener(offsetChangedListener)
}
}
+ override fun onDestroyView() {
+ settingsActivity?.appBarLayout?.apply {
+ removeOnOffsetChangedListener(offsetChangedListener)
+
+ setLiftOnScrollTargetView(null)
+ }
+
+ super.onDestroyView()
+ }
+
+ @CallSuper
+ override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
+ setPreferencesFromResource(preferencesResId, rootKey)
+ }
+
+ @CallSuper
override fun onCreateRecyclerView(
inflater: LayoutInflater,
parent: ViewGroup,
savedInstanceState: Bundle?
- ) = super.onCreateRecyclerView(inflater, parent, savedInstanceState).also {
- it.clipToPadding = false
+ ) = super.onCreateRecyclerView(inflater, parent, savedInstanceState).apply {
+ clipToPadding = false
+ isVerticalScrollBarEnabled = false
+
+ ViewCompat.setOnApplyWindowInsetsListener(this) { _, windowInsets ->
+ val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
+
+ updatePadding(
+ bottom = insets.bottom,
+ left = insets.left,
+ right = insets.right,
+ )
+
+ windowInsets
+ }
}
}
- class RootSettingsFragment : SettingsFragment() {
+ class RootSettingsFragment : SettingsFragment(R.xml.root_preferences) {
private val enableZsl by lazy { findPreference<SwitchPreference>("enable_zsl")!! }
private val photoCaptureMode by lazy {
findPreference<ListPreference>("photo_capture_mode")!!
@@ -129,7 +175,8 @@
@Suppress("UnsafeOptInUsageError")
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
- setPreferencesFromResource(R.xml.root_preferences, rootKey)
+ super.onCreatePreferences(savedInstanceState, rootKey)
+
saveLocation?.let {
// Reset location back to off if permissions aren't granted
it.isChecked = it.isChecked && permissionsUtils.locationPermissionsGranted()
@@ -149,9 +196,5 @@
}
}
- class ProcessingSettingsFragment : SettingsFragment() {
- override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
- setPreferencesFromResource(R.xml.processing_preferences, rootKey)
- }
- }
+ class ProcessingSettingsFragment : SettingsFragment(R.xml.processing_preferences)
}
diff --git a/app/src/main/java/org/lineageos/aperture/ext/AppBarLayout.kt b/app/src/main/java/org/lineageos/aperture/ext/AppBarLayout.kt
new file mode 100644
index 0000000..2376941
--- /dev/null
+++ b/app/src/main/java/org/lineageos/aperture/ext/AppBarLayout.kt
@@ -0,0 +1,24 @@
+/*
+ * SPDX-FileCopyrightText: 2024 The LineageOS Project
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.lineageos.aperture.ext
+
+import androidx.annotation.Px
+import androidx.coordinatorlayout.widget.CoordinatorLayout
+import com.google.android.material.appbar.AppBarLayout
+import kotlin.reflect.safeCast
+
+fun AppBarLayout.setOffset(@Px offsetPx: Int, coordinatorLayout: CoordinatorLayout) {
+ val params = CoordinatorLayout.LayoutParams::class.safeCast(layoutParams) ?: return
+ AppBarLayout.Behavior::class.safeCast(params.behavior)?.onNestedPreScroll(
+ coordinatorLayout,
+ this,
+ this,
+ 0,
+ offsetPx,
+ intArrayOf(0, 0),
+ 0
+ )
+}
diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml
index 1475a16..0765e3c 100644
--- a/app/src/main/res/layout/activity_settings.xml
+++ b/app/src/main/res/layout/activity_settings.xml
@@ -6,23 +6,26 @@
<androidx.coordinatorlayout.widget.CoordinatorLayout 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/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SettingsActivity">
<com.google.android.material.appbar.AppBarLayout
+ android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:fitsSystemWindows="true">
+ android:fitsSystemWindows="true"
+ app:liftOnScrollTargetViewId="@+id/settings">
<com.google.android.material.appbar.CollapsingToolbarLayout
style="?attr/collapsingToolbarLayoutLargeStyle"
android:layout_width="match_parent"
android:layout_height="179dp"
- app:collapsedTitleTextAppearance="@style/Theme.Aperture.Camera.ToolbarCollapsed"
+ app:collapsedTitleTextAppearance="@style/Theme.SettingsLib.ToolbarCollapsedTextAppearance"
app:expandedTitleMarginBottom="31dp"
app:expandedTitleMarginStart="24dp"
- app:expandedTitleTextAppearance="@style/Theme.Aperture.Camera.ToolbarExpanded"
+ app:expandedTitleTextAppearance="@style/Theme.SettingsLib.ToolbarExpandedTextAppearance"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
app:titleCollapseMode="fade"
app:toolbarId="@id/toolbar">
@@ -38,16 +41,10 @@
</com.google.android.material.appbar.AppBarLayout>
- <androidx.core.widget.NestedScrollView
+ <FrameLayout
+ android:id="@+id/settings"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:layout_behavior="@string/appbar_scrolling_view_behavior">
-
- <FrameLayout
- android:id="@+id/settings"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginStart="8dp" />
- </androidx.core.widget.NestedScrollView>
+ app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index c015a64..d84a99d 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -23,45 +23,6 @@
<item name="android:windowLightStatusBar">?attr/isLightTheme</item>
</style>
- <!-- Settings activity theme. -->
- <style name="Theme.Aperture.Settings">
- <item name="android:switchStyle">@style/Theme.Aperture.Settings.Switch</item>
- <item name="alertDialogTheme">@style/Theme.Aperture.Settings.AlertDialog</item>
- <item name="materialAlertDialogTheme">@style/Theme.Aperture.Settings.AlertDialog</item>
- <item name="preferenceTheme">@style/Theme.Aperture.Settings.Preference</item>
- </style>
-
- <!-- Settings alert dialog theme. -->
- <style name="Theme.Aperture.Settings.AlertDialog" parent="ThemeOverlay.Material3.MaterialAlertDialog">
- <item name="alertDialogStyle">@style/Theme.Aperture.Settings.AlertDialogStyle</item>
- <item name="dialogCornerRadius">28dp</item>
- <item name="android:background">@drawable/dialog_preference_background</item>
- </style>
-
- <!-- Settings alert dialog style. -->
- <style name="Theme.Aperture.Settings.AlertDialogStyle" parent="MaterialAlertDialog.Material3">
- <item name="shapeAppearance">@style/ShapeAppearance.Material3.MediumComponent</item>
- <item name="shapeAppearanceOverlay">@null</item>
- </style>
-
- <!-- Settings message box -->
- <style name="Theme.Aperture.Settings.MessageBox">
- <item name="selectable">false</item>
- </style>
-
- <!-- Settings preference style. -->
- <style name="Theme.Aperture.Settings.Preference" parent="PreferenceThemeOverlay">
- <item name="android:tint">?attr/colorOnSurface</item>
- </style>
-
- <!-- Settings switch theme. -->
- <style name="Theme.Aperture.Settings.Switch" parent="@android:style/Widget.Material.CompoundButton.Switch">
- <item name="android:switchMinWidth">52dp</item>
- <item name="android:minHeight">48dp</item>
- <item name="android:track">@drawable/settingslib_switch_track</item>
- <item name="android:thumb">@drawable/settingslib_switch_thumb</item>
- </style>
-
<!-- Secondary bar icons base theme -->
<style name="Theme.Aperture.Camera.SecondaryBarButton">
<item name="tint">@color/secondary_bar_button_icon</item>
@@ -90,17 +51,6 @@
<item name="android:layout_height">40dp</item>
</style>
- <!-- Collapsing toolbar style -->
- <style name="Theme.Aperture.Camera.ToolbarCollapsed" parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
- <item name="android:fontFamily">sans-serif</item>
- <item name="android:textSize">20sp</item>
- </style>
-
- <style name="Theme.Aperture.Camera.ToolbarExpanded" parent="Theme.Aperture.Camera.ToolbarCollapsed">
- <item name="android:textSize">36sp</item>
- <item name="android:drawablePadding">10dp</item>
- </style>
-
<!-- Info chip -->
<style name="Theme.Aperture.Camera.InfoChip" />
diff --git a/app/src/main/res/values/themes_settingslib.xml b/app/src/main/res/values/themes_settingslib.xml
new file mode 100644
index 0000000..5ea7e7c
--- /dev/null
+++ b/app/src/main/res/values/themes_settingslib.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ SPDX-FileCopyrightText: 2024 The LineageOS Project
+ SPDX-License-Identifier: Apache-2.0
+-->
+<resources>
+ <!-- Settings activity theme. -->
+ <style name="Theme.SettingsLib" parent="Theme.Material3.DayNight.NoActionBar">
+ <item name="android:listPreferredItemPaddingLeft">24dp</item>
+ <item name="android:listPreferredItemPaddingStart">24dp</item>
+ <item name="android:navigationBarColor">@android:color/transparent</item>
+ <item name="android:statusBarColor">@android:color/transparent</item>
+ <item name="android:switchStyle">@style/Theme.SettingsLib.Switch</item>
+ <item name="android:windowLightStatusBar">?attr/isLightTheme</item>
+ <item name="alertDialogTheme">@style/Theme.SettingsLib.AlertDialog</item>
+ <item name="materialAlertDialogTheme">@style/Theme.SettingsLib.AlertDialog</item>
+ <item name="preferenceTheme">@style/Theme.SettingsLib.PreferenceTheme</item>
+ </style>
+
+ <!-- Settings alert dialog theme. -->
+ <style name="Theme.SettingsLib.AlertDialog" parent="ThemeOverlay.Material3.MaterialAlertDialog">
+ <item name="android:background">@drawable/dialog_preference_background</item>
+ <item name="dialogCornerRadius">28dp</item>
+ </style>
+
+ <!-- Settings switch theme. -->
+ <style name="Theme.SettingsLib.Switch" parent="@android:style/Widget.Material.CompoundButton.Switch">
+ <item name="android:switchMinWidth">52dp</item>
+ <item name="android:minHeight">48dp</item>
+ <item name="android:track">@drawable/settingslib_switch_track</item>
+ <item name="android:thumb">@drawable/settingslib_switch_thumb</item>
+ </style>
+
+ <!-- Settings collapsing toolbar style -->
+ <style name="Theme.SettingsLib.ToolbarCollapsedTextAppearance" parent="TextAppearance.Material3.ActionBar.Title" />
+
+ <style name="Theme.SettingsLib.ToolbarExpandedTextAppearance" parent="TextAppearance.Material3.HeadlineMedium">
+ <item name="android:drawablePadding">10dp</item>
+ <item name="android:textSize">36sp</item>
+ </style>
+
+ <!-- Settings preference style. -->
+ <style name="Theme.SettingsLib.PreferenceTheme" parent="PreferenceThemeOverlay">
+ <item name="android:divider">@android:color/transparent</item>
+ <item name="android:dividerHeight">0dp</item>
+ <item name="android:listPreferredItemPaddingLeft">32dp</item>
+ <item name="android:listPreferredItemPaddingStart">32dp</item>
+ <item name="android:tint">?attr/colorOnSurface</item>
+ </style>
+</resources>
diff --git a/app/src/main/res/xml/processing_preferences.xml b/app/src/main/res/xml/processing_preferences.xml
index ccccd5c..0f3b49e 100644
--- a/app/src/main/res/xml/processing_preferences.xml
+++ b/app/src/main/res/xml/processing_preferences.xml
@@ -10,8 +10,8 @@
app:title="@string/processing_title">
<Preference
- style="@style/Theme.Aperture.Settings.MessageBox"
app:icon="@drawable/ic_info"
+ app:selectable="false"
app:summary="@string/processing_info" />
<ListPreference