Replace deprecated menu overrides (#443)

* Migrated to menu provider

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Removed override

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Cleanup

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Fixed menus

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Minor changes

---------

Signed-off-by: Arnau Mora <arnyminerz@proton.me>
Co-authored-by: Ricki Hirner <hirner@bitfire.at>
This commit is contained in:
Arnau Mora 2023-10-16 14:30:26 +01:00 committed by GitHub
parent c8cd6d780c
commit 599c905610
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 255 additions and 126 deletions

View file

@ -18,6 +18,7 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.core.text.HtmlCompat
import androidx.core.view.MenuProvider
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
@ -81,14 +82,24 @@ class AboutActivity: AppCompatActivity() {
binding.viewpager.adapter = TabsAdapter(supportFragmentManager)
binding.tabs.setupWithViewPager(binding.viewpager, false)
addMenuProvider(object : MenuProvider {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.activity_about, menu)
}
override fun onMenuItemSelected(menuItem: MenuItem) =
when (menuItem.itemId) {
R.id.show_website -> {
showWebsite()
true
}
else -> false
}
})
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.activity_about, menu)
return true
}
fun showWebsite(item: MenuItem) {
fun showWebsite() {
UiUtils.launchUri(this, App.homepageUrl(this))
}

View file

@ -20,10 +20,13 @@ import android.provider.Settings
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.annotation.AnyThread
import androidx.core.content.ContextCompat
import androidx.core.view.MenuHost
import androidx.core.view.MenuProvider
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.AndroidViewModel
@ -58,8 +61,6 @@ class AccountListFragment: Fragment() {
private var syncStatusSnackbar: Snackbar? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
setHasOptionsMenu(true)
_binding = AccountListBinding.inflate(inflater, container, false)
return binding.root
}
@ -132,16 +133,28 @@ class AccountListFragment: Fragment() {
accountAdapter.submitList(accounts)
requireActivity().invalidateOptionsMenu()
}
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) =
inflater.inflate(R.menu.activity_accounts, menu)
requireActivity().addMenuProvider(object : MenuProvider {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.activity_accounts, menu)
}
override fun onPrepareOptionsMenu(menu: Menu) {
// Show "Sync all" only when there is at least one account
model.accounts.value?.let { accounts ->
menu.findItem(R.id.syncAll).setVisible(accounts.isNotEmpty())
}
override fun onMenuItemSelected(menuItem: MenuItem) =
when (menuItem.itemId) {
R.id.syncAll -> {
(activity as AccountsActivity).syncAllAccounts()
true
}
else -> false
}
override fun onPrepareMenu(menu: Menu) {
// Show "Sync all" only when there is at least one account
model.accounts.value?.let { accounts ->
menu.findItem(R.id.syncAll).setVisible(accounts.isNotEmpty())
}
}
})
}
override fun onResume() {

View file

@ -109,7 +109,7 @@ class AccountsActivity: AppCompatActivity(), NavigationView.OnNavigationItemSele
private fun allAccounts() =
AccountManager.get(this).getAccountsByType(getString(R.string.account_type))
fun syncAllAccounts(item: MenuItem? = null) {
fun syncAllAccounts() {
if (Build.VERSION.SDK_INT >= 25)
getSystemService<ShortcutManager>()?.reportShortcutUsed(UiUtils.SHORTCUT_SYNC_ALL)

View file

@ -13,10 +13,12 @@ import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.TooltipCompat
import androidx.core.view.MenuProvider
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.*
import androidx.viewpager2.adapter.FragmentStateAdapter
@ -105,27 +107,45 @@ class AccountActivity: AppCompatActivity() {
SyncWorker.enqueueAllAuthorities(this, model.account)
}
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.activity_account, menu)
return true
addMenuProvider(object : MenuProvider {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.activity_account, menu)
}
override fun onMenuItemSelected(menuItem: MenuItem) =
when (menuItem.itemId) {
R.id.settings -> {
openAccountSettings()
true
}
R.id.rename_account -> {
renameAccount()
true
}
R.id.delete_account -> {
deleteAccountDialog()
true
}
else -> false
}
})
}
// menu actions
fun openAccountSettings(menuItem: MenuItem) {
fun openAccountSettings() {
val intent = Intent(this, SettingsActivity::class.java)
intent.putExtra(SettingsActivity.EXTRA_ACCOUNT, model.account)
startActivity(intent, null)
}
fun renameAccount(menuItem: MenuItem) {
fun renameAccount() {
RenameAccountFragment.newInstance(model.account).show(supportFragmentManager, null)
}
fun deleteAccount(menuItem: MenuItem) {
fun deleteAccountDialog() {
MaterialAlertDialogBuilder(this)
.setIcon(R.drawable.ic_error)
.setTitle(R.string.account_delete_confirmation_title)

View file

@ -5,7 +5,10 @@
package at.bitfire.davdroid.ui.account
import android.content.Intent
import android.os.Bundle
import android.view.*
import androidx.core.view.MenuHost
import androidx.core.view.MenuProvider
import androidx.fragment.app.FragmentManager
import at.bitfire.davdroid.util.PermissionUtils
import at.bitfire.davdroid.R
@ -22,26 +25,39 @@ class AddressBooksFragment: CollectionsFragment() {
override val noCollectionsStringId = R.string.account_no_address_books
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) =
inflater.inflate(R.menu.carddav_actions, menu)
override fun onPrepareOptionsMenu(menu: Menu) {
menu.findItem(R.id.create_address_book).isVisible = model.hasWriteableCollections.value ?: false
super.onPrepareOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (super.onOptionsItemSelected(item))
return true
if (item.itemId == R.id.create_address_book) {
val intent = Intent(requireActivity(), CreateAddressBookActivity::class.java)
intent.putExtra(CreateAddressBookActivity.EXTRA_ACCOUNT, accountModel.account)
startActivity(intent)
return true
private val menuProvider = object : CollectionsMenuProvider() {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.carddav_actions, menu)
}
return false
override fun onPrepareMenu(menu: Menu) {
super.onPrepareMenu(menu)
menu.findItem(R.id.create_address_book).isVisible = model.hasWriteableCollections.value ?: false
}
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
if (super.onMenuItemSelected(menuItem))
return true
if (menuItem.itemId == R.id.create_address_book) {
val intent = Intent(requireActivity(), CreateAddressBookActivity::class.java)
intent.putExtra(CreateAddressBookActivity.EXTRA_ACCOUNT, accountModel.account)
startActivity(intent)
return true
}
return false
}
}
override fun onResume() {
super.onResume()
requireActivity().addMenuProvider(menuProvider)
}
override fun onPause() {
super.onPause()
requireActivity().removeMenuProvider(menuProvider)
}
override fun checkPermissions() {

View file

@ -5,7 +5,10 @@
package at.bitfire.davdroid.ui.account
import android.content.Intent
import android.os.Bundle
import android.view.*
import androidx.core.view.MenuHost
import androidx.core.view.MenuProvider
import androidx.fragment.app.FragmentManager
import at.bitfire.davdroid.Constants
import at.bitfire.davdroid.util.PermissionUtils
@ -18,26 +21,40 @@ class CalendarsFragment: CollectionsFragment() {
override val noCollectionsStringId = R.string.account_no_calendars
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) =
inflater.inflate(R.menu.caldav_actions, menu)
override fun onPrepareOptionsMenu(menu: Menu) {
menu.findItem(R.id.create_calendar).isVisible = model.hasWriteableCollections.value ?: false
super.onPrepareOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (super.onOptionsItemSelected(item))
return true
if (item.itemId == R.id.create_calendar) {
val intent = Intent(requireActivity(), CreateCalendarActivity::class.java)
intent.putExtra(CreateCalendarActivity.EXTRA_ACCOUNT, accountModel.account)
startActivity(intent)
return true
private val menuProvider = object : CollectionsMenuProvider() {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.caldav_actions, menu)
}
return false
override fun onPrepareMenu(menu: Menu) {
super.onPrepareMenu(menu)
menu.findItem(R.id.create_calendar).isVisible = model.hasWriteableCollections.value ?: false
}
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
if (super.onMenuItemSelected(menuItem)) {
return true
}
if (menuItem.itemId == R.id.create_calendar) {
val intent = Intent(requireActivity(), CreateCalendarActivity::class.java)
intent.putExtra(CreateCalendarActivity.EXTRA_ACCOUNT, accountModel.account)
startActivity(intent)
return true
}
return false
}
}
override fun onResume() {
super.onResume()
requireActivity().addMenuProvider(menuProvider)
}
override fun onPause() {
super.onPause()
requireActivity().removeMenuProvider(menuProvider)
}

View file

@ -13,6 +13,9 @@ import android.provider.CalendarContract
import android.provider.ContactsContract
import android.view.*
import android.widget.PopupMenu
import androidx.annotation.CallSuper
import androidx.core.view.MenuHost
import androidx.core.view.MenuProvider
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.activityViewModels
@ -66,11 +69,6 @@ abstract class CollectionsFragment: Fragment(), SwipeRefreshLayout.OnRefreshList
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
abstract val noCollectionsStringId: Int
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
@ -86,17 +84,17 @@ abstract class CollectionsFragment: Fragment(), SwipeRefreshLayout.OnRefreshList
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
model.isRefreshing.observe(viewLifecycleOwner, Observer { nowRefreshing ->
model.isRefreshing.observe(viewLifecycleOwner) { nowRefreshing ->
binding.swipeRefresh.isRefreshing = nowRefreshing
})
model.hasWriteableCollections.observe(viewLifecycleOwner, Observer {
}
model.hasWriteableCollections.observe(viewLifecycleOwner) {
requireActivity().invalidateOptionsMenu()
})
model.collectionColors.observe(viewLifecycleOwner, Observer { colors: List<Int?> ->
}
model.collectionColors.observe(viewLifecycleOwner) { colors: List<Int?> ->
val realColors = colors.filterNotNull()
if (realColors.isNotEmpty())
binding.swipeRefresh.setColorSchemeColors(*realColors.toIntArray())
})
}
binding.swipeRefresh.setOnRefreshListener(this)
val updateProgress = Observer<Boolean> {
@ -128,11 +126,11 @@ abstract class CollectionsFragment: Fragment(), SwipeRefreshLayout.OnRefreshList
val adapter = createAdapter()
binding.list.layoutManager = LinearLayoutManager(requireActivity())
binding.list.adapter = adapter
model.collections.observe(viewLifecycleOwner, Observer { data ->
model.collections.observe(viewLifecycleOwner) { data ->
lifecycleScope.launch {
adapter.submitData(data)
}
})
}
adapter.addLoadStateListener { loadStates ->
if (loadStates.refresh is LoadState.NotLoading) {
if (adapter.itemCount > 0) {
@ -148,31 +146,6 @@ abstract class CollectionsFragment: Fragment(), SwipeRefreshLayout.OnRefreshList
binding.noCollections.setText(noCollectionsStringId)
}
override fun onPrepareOptionsMenu(menu: Menu) {
menu.findItem(R.id.showOnlyPersonal).let { showOnlyPersonal ->
accountModel.showOnlyPersonal.value?.let { value ->
showOnlyPersonal.isChecked = value
}
accountModel.showOnlyPersonalWritable.value?.let { writable ->
showOnlyPersonal.isEnabled = writable
}
}
}
override fun onOptionsItemSelected(item: MenuItem) =
when (item.itemId) {
R.id.refresh -> {
onRefresh()
true
}
R.id.showOnlyPersonal -> {
accountModel.toggleShowOnlyPersonal()
true
}
else ->
false
}
override fun onRefresh() {
model.refresh()
}
@ -223,6 +196,38 @@ abstract class CollectionsFragment: Fragment(), SwipeRefreshLayout.OnRefreshList
}
abstract inner class CollectionsMenuProvider : MenuProvider {
abstract override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater)
@CallSuper
override fun onPrepareMenu(menu: Menu) {
menu.findItem(R.id.showOnlyPersonal).let { showOnlyPersonal ->
accountModel.showOnlyPersonal.value?.let { value ->
showOnlyPersonal.isChecked = value
}
accountModel.showOnlyPersonalWritable.value?.let { writable ->
showOnlyPersonal.isEnabled = writable
}
}
}
@CallSuper
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
return when (menuItem.itemId) {
R.id.refresh -> {
onRefresh()
true
}
R.id.showOnlyPersonal -> {
accountModel.toggleShowOnlyPersonal()
true
}
else ->
false
}
}
}
class CollectionPopupListener(
private val accountModel: AccountActivity.Model,
private val item: Collection,

View file

@ -60,6 +60,32 @@ class WebcalFragment: CollectionsFragment() {
}
}
private val menuProvider = object : CollectionsMenuProvider() {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.caldav_actions, menu)
}
override fun onPrepareMenu(menu: Menu) {
super.onPrepareMenu(menu)
menu.findItem(R.id.create_calendar).isVisible = false
}
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
if (super.onMenuItemSelected(menuItem)) {
return true
}
if (menuItem.itemId == R.id.create_calendar) {
val intent = Intent(requireActivity(), CreateCalendarActivity::class.java)
intent.putExtra(CreateCalendarActivity.EXTRA_ACCOUNT, accountModel.account)
startActivity(intent)
return true
}
return false
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -68,12 +94,14 @@ class WebcalFragment: CollectionsFragment() {
})
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) =
inflater.inflate(R.menu.caldav_actions, menu)
override fun onResume() {
super.onResume()
requireActivity().addMenuProvider(menuProvider)
}
override fun onPrepareOptionsMenu(menu: Menu) {
super.onPrepareOptionsMenu(menu)
menu.findItem(R.id.create_calendar).isVisible = false
override fun onPause() {
super.onPause()
requireActivity().removeMenuProvider(menuProvider)
}

View file

@ -7,24 +7,26 @@ package at.bitfire.davdroid.ui.webdav
import android.content.Context
import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import androidx.activity.viewModels
import androidx.annotation.WorkerThread
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.MenuProvider
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.lifecycleScope
import at.bitfire.dav4jvm.DavResource
import at.bitfire.dav4jvm.UrlUtils
import at.bitfire.davdroid.App
import at.bitfire.davdroid.network.HttpClient
import at.bitfire.davdroid.R
import at.bitfire.davdroid.databinding.ActivityAddWebdavMountBinding
import at.bitfire.davdroid.db.AppDatabase
import at.bitfire.davdroid.db.Credentials
import at.bitfire.davdroid.db.WebDavMount
import at.bitfire.davdroid.log.Logger
import at.bitfire.davdroid.network.HttpClient
import at.bitfire.davdroid.ui.UiUtils
import at.bitfire.davdroid.webdav.CredentialsStore
import at.bitfire.davdroid.webdav.DavDocumentsProvider
@ -66,14 +68,25 @@ class AddWebdavMountActivity: AppCompatActivity() {
binding.addMount.setOnClickListener {
validate()
}
addMenuProvider(object : MenuProvider {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.activity_add_webdav_mount, menu)
}
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
return when (menuItem.itemId) {
R.id.help -> {
onShowHelp()
true
}
else -> false
}
}
})
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.activity_add_webdav_mount, menu)
return true
}
fun onShowHelp(item: MenuItem) {
fun onShowHelp() {
UiUtils.launchUri(this,
App.homepageUrl(this).buildUpon().appendPath("tested-with").build())
}

View file

@ -15,6 +15,7 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.text.HtmlCompat
import androidx.core.view.MenuProvider
import androidx.lifecycle.*
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.LinearLayoutManager
@ -88,14 +89,25 @@ class WebdavMountsActivity: AppCompatActivity() {
binding.add.setOnClickListener {
startActivity(Intent(this, AddWebdavMountActivity::class.java))
}
addMenuProvider(object : MenuProvider {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.activity_webdav_mounts, menu)
}
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
return when (menuItem.itemId) {
R.id.help -> {
onShowHelp()
true
}
else -> false
}
}
})
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.activity_webdav_mounts, menu)
return true
}
fun onShowHelp(item: MenuItem) {
fun onShowHelp() {
UiUtils.launchUri(this, helpUrl())
}

View file

@ -3,9 +3,9 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/show_website"
android:icon="@drawable/ic_home"
android:title="@string/navigation_drawer_website"
app:showAsAction="ifRoom"
android:onClick="showWebsite" />
app:showAsAction="ifRoom" />
</menu>

View file

@ -7,17 +7,14 @@
<item android:id="@+id/settings"
android:icon="@drawable/ic_settings"
android:title="@string/account_settings"
android:onClick="openAccountSettings"
app:showAsAction="ifRoom"/>
<item android:id="@+id/rename_account"
android:title="@string/account_rename"
android:onClick="renameAccount"
app:showAsAction="never"/>
<item android:id="@+id/delete_account"
android:title="@string/account_delete"
android:onClick="deleteAccount"
app:showAsAction="never"/>
</group>

View file

@ -5,7 +5,6 @@
<item android:id="@+id/syncAll"
android:icon="@drawable/ic_sync"
android:title="@string/accounts_sync_all"
android:onClick="syncAllAccounts"
app:showAsAction="ifRoom"/>
</menu>

View file

@ -6,7 +6,6 @@
android:id="@+id/help"
android:icon="@drawable/ic_help"
android:title="@string/help"
app:showAsAction="always"
android:onClick="onShowHelp" />
app:showAsAction="always" />
</menu>

View file

@ -6,7 +6,6 @@
android:id="@+id/help"
android:icon="@drawable/ic_help"
android:title="@string/help"
app:showAsAction="always"
android:onClick="onShowHelp" />
app:showAsAction="always" />
</menu>