From bfec814b435e4bcb2acf7eba75eddcbedfa45eb5 Mon Sep 17 00:00:00 2001 From: tzugen Date: Tue, 16 May 2023 18:00:38 +0200 Subject: [PATCH 1/3] Upgrade material to 1.9.0 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 057f57a7..887fe623 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ preferences = "1.2.0" media3 = "1.0.2" androidSupport = "1.6.0" -materialDesign = "1.8.0" +materialDesign = "1.9.0" constraintLayout = "2.1.4" multidex = "2.0.1" room = "2.5.1" From bfe24e5dfdd152b17361de5eafacb31cede20b29 Mon Sep 17 00:00:00 2001 From: tzugen Date: Mon, 5 Jun 2023 17:23:48 +0200 Subject: [PATCH 2/3] Modernize backhandling to support predictive back handling --- ultrasonic/src/main/AndroidManifest.xml | 1 + .../ultrasonic/activity/NavigationActivity.kt | 48 ++++++++++++------- .../ultrasonic/fragment/EditServerFragment.kt | 30 +++++++++--- .../fragment/OnBackPressedHandler.kt | 15 ------ 4 files changed, 56 insertions(+), 38 deletions(-) delete mode 100644 ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/OnBackPressedHandler.kt diff --git a/ultrasonic/src/main/AndroidManifest.xml b/ultrasonic/src/main/AndroidManifest.xml index 266ccd79..332bb4a2 100644 --- a/ultrasonic/src/main/AndroidManifest.xml +++ b/ultrasonic/src/main/AndroidManifest.xml @@ -33,6 +33,7 @@ android:supportsRtl="false" android:preserveLegacyExternalStorage="true" tools:ignore="UnusedAttribute"> + diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt index 8ed8c8bc..416d5e12 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt @@ -21,6 +21,7 @@ import android.view.Menu import android.view.MenuItem import android.view.View import android.widget.ImageView +import androidx.activity.OnBackPressedCallback import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar import androidx.core.content.ContextCompat @@ -51,7 +52,6 @@ import org.moire.ultrasonic.R import org.moire.ultrasonic.app.UApp import org.moire.ultrasonic.data.ActiveServerProvider import org.moire.ultrasonic.data.ServerSettingDao -import org.moire.ultrasonic.fragment.OnBackPressedHandler import org.moire.ultrasonic.model.ServerSettingsModel import org.moire.ultrasonic.provider.SearchSuggestionProvider import org.moire.ultrasonic.service.MediaPlayerLifecycleSupport @@ -126,6 +126,8 @@ class NavigationActivity : AppCompatActivity() { navigationView = findViewById(R.id.nav_view) drawerLayout = findViewById(R.id.drawer_layout) + setupDrawerLayout(drawerLayout!!) + val toolbar = findViewById(R.id.toolbar) setSupportActionBar(toolbar) @@ -212,6 +214,27 @@ class NavigationActivity : AppCompatActivity() { } } + private fun setupDrawerLayout(drawerLayout: DrawerLayout) { + onBackPressedDispatcher.addCallback(this, closeNavigationDrawerOnBack) + drawerLayout.addDrawerListener(object : DrawerLayout.DrawerListener { + override fun onDrawerSlide(drawerView: View, slideOffset: Float) { + // Nothing + } + + override fun onDrawerOpened(drawerView: View) { + closeNavigationDrawerOnBack.isEnabled = true + } + + override fun onDrawerClosed(drawerView: View) { + closeNavigationDrawerOnBack.isEnabled = false + } + + override fun onDrawerStateChanged(newState: Int) { + // Nothing + } + }) + } + override fun onResume() { Timber.d("onResume called") super.onResume() @@ -328,15 +351,11 @@ class NavigationActivity : AppCompatActivity() { setupActionBarWithNavController(navController, appBarConfig) } - override fun onBackPressed() { - if (drawerLayout?.isDrawerVisible(GravityCompat.START) == true) { - this.drawerLayout?.closeDrawer(GravityCompat.START) - } else { - val currentFragment = host!!.childFragmentManager.fragments.last() - if (currentFragment is OnBackPressedHandler) currentFragment.onBackPressed() - else super.onBackPressed() + private val closeNavigationDrawerOnBack = object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + drawerLayout?.closeDrawer(GravityCompat.START) + } } - } override fun onCreateOptionsMenu(menu: Menu): Boolean { val retValue = super.onCreateOptionsMenu(menu) @@ -352,17 +371,12 @@ class NavigationActivity : AppCompatActivity() { super.onOptionsItemSelected(item) } + // TODO: Why is this needed? Shouldn't it just work by default? override fun onSupportNavigateUp(): Boolean { - val currentFragment = host!!.childFragmentManager.fragments.last() - return if (currentFragment is OnBackPressedHandler) { - currentFragment.onBackPressed() - true - } else { - findNavController(R.id.nav_host_fragment).navigateUp(appBarConfiguration) - } + return findNavController(R.id.nav_host_fragment).navigateUp(appBarConfiguration) } - // TODO Test if this works with external Intents + // TODO: Test if this works with external Intents // android.intent.action.SEARCH and android.media.action.MEDIA_PLAY_FROM_SEARCH calls here override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/EditServerFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/EditServerFragment.kt index 73d3a0ba..b50cfb67 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/EditServerFragment.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/EditServerFragment.kt @@ -7,12 +7,14 @@ package org.moire.ultrasonic.fragment +import android.content.Context import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Button import android.widget.ImageView +import androidx.activity.OnBackPressedCallback import androidx.appcompat.app.AlertDialog import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment @@ -52,7 +54,7 @@ private const val DIALOG_PADDING = 12 /** * Displays a form where server settings can be created / edited */ -class EditServerFragment : Fragment(), OnBackPressedHandler { +class EditServerFragment : Fragment() { private val serverSettingsModel: ServerSettingsModel by viewModel() private val activeServerProvider: ActiveServerProvider by inject() @@ -82,6 +84,13 @@ class EditServerFragment : Fragment(), OnBackPressedHandler { super.onCreate(savedInstanceState) } + override fun onAttach(context: Context) { + requireActivity().onBackPressedDispatcher.addCallback( + this, confirmCloseCallback + ) + super.onAttach(context) + } + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -189,11 +198,25 @@ class EditServerFragment : Fragment(), OnBackPressedHandler { } } + private val confirmCloseCallback = object : OnBackPressedCallback( + true // default to enabled + ) { + override fun handleOnBackPressed() { + finishActivity() + } + } + override fun onStop() { Util.hideKeyboard(activity) + confirmCloseCallback.isEnabled = false super.onStop() } + override fun onResume() { + confirmCloseCallback.isEnabled = true + super.onResume() + } + private fun correctServerAddress() { serverAddressEditText?.editText?.setText( serverAddressEditText?.editText?.text?.trim(' ', '/') @@ -206,11 +229,6 @@ class EditServerFragment : Fragment(), OnBackPressedHandler { image?.setTint(currentColor) serverColorImageView?.background = image } - - override fun onBackPressed() { - finishActivity() - } - override fun onSaveInstanceState(savedInstanceState: Bundle) { savedInstanceState.putString( ::serverNameEditText.name, serverNameEditText!!.editText?.text.toString() diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/OnBackPressedHandler.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/OnBackPressedHandler.kt deleted file mode 100644 index c34ca2dd..00000000 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/OnBackPressedHandler.kt +++ /dev/null @@ -1,15 +0,0 @@ -/* - * OnBackPressedHandler.kt - * Copyright (C) 2009-2022 Ultrasonic developers - * - * Distributed under terms of the GNU GPLv3 license. - */ - -package org.moire.ultrasonic.fragment - -/** - * Interface for fragments handling their own Back button - */ -interface OnBackPressedHandler { - fun onBackPressed() -} From fd22c0f8b56caa4b7271de66a9a656e98ba5f7ab Mon Sep 17 00:00:00 2001 From: tzugen Date: Tue, 6 Jun 2023 10:52:00 +0200 Subject: [PATCH 3/3] Add little dropdown icon to server selector header to show interactivity. --- .../ultrasonic/activity/NavigationActivity.kt | 15 +++++++--- .../src/main/res/drawable/arrow_drop_down.xml | 5 ++++ .../main/res/layout/navigation_activity.xml | 1 + .../src/main/res/layout/navigation_header.xml | 30 ++++++++++++++----- 4 files changed, 40 insertions(+), 11 deletions(-) create mode 100644 ultrasonic/src/main/res/drawable/arrow_drop_down.xml diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt index 416d5e12..51c75e79 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt @@ -338,11 +338,18 @@ class NavigationActivity : AppCompatActivity() { selectServerButton = navigationView?.getHeaderView(0)?.findViewById(R.id.header_select_server) - selectServerButton?.setOnClickListener { + val dropDownButton: ImageView? = + navigationView?.getHeaderView(0)?.findViewById(R.id.edit_server_button) + + val onClick: (View) -> Unit = { if (drawerLayout?.isDrawerVisible(GravityCompat.START) == true) this.drawerLayout?.closeDrawer(GravityCompat.START) navController.navigate(R.id.serverSelectorFragment) } + + selectServerButton?.setOnClickListener(onClick) + dropDownButton?.setOnClickListener(onClick) + headerBackgroundImage = navigationView?.getHeaderView(0)?.findViewById(R.id.img_header_bg) } @@ -352,10 +359,10 @@ class NavigationActivity : AppCompatActivity() { } private val closeNavigationDrawerOnBack = object : OnBackPressedCallback(true) { - override fun handleOnBackPressed() { - drawerLayout?.closeDrawer(GravityCompat.START) - } + override fun handleOnBackPressed() { + drawerLayout?.closeDrawer(GravityCompat.START) } + } override fun onCreateOptionsMenu(menu: Menu): Boolean { val retValue = super.onCreateOptionsMenu(menu) diff --git a/ultrasonic/src/main/res/drawable/arrow_drop_down.xml b/ultrasonic/src/main/res/drawable/arrow_drop_down.xml new file mode 100644 index 00000000..0a9fd3a6 --- /dev/null +++ b/ultrasonic/src/main/res/drawable/arrow_drop_down.xml @@ -0,0 +1,5 @@ + + + diff --git a/ultrasonic/src/main/res/layout/navigation_activity.xml b/ultrasonic/src/main/res/layout/navigation_activity.xml index 867f1f6b..ef421eac 100644 --- a/ultrasonic/src/main/res/layout/navigation_activity.xml +++ b/ultrasonic/src/main/res/layout/navigation_activity.xml @@ -42,6 +42,7 @@ - + app:layout_constraintTop_toTopOf="parent" />