diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/ActivitiesFragment.kt b/app/src/main/java/com/owncloud/android/ui/fragment/ActivitiesFragment.kt index cf2ca680b634..05733b199836 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/ActivitiesFragment.kt +++ b/app/src/main/java/com/owncloud/android/ui/fragment/ActivitiesFragment.kt @@ -60,8 +60,7 @@ class ActivitiesFragment : @Inject lateinit var userAccountManager: UserAccountManager - private var _binding: FragmentActivitiesBinding? = null - internal val binding get() = _binding!! + private var binding: FragmentActivitiesBinding? = null private var adapter: ActivityListAdapter? = null private var lastGiven: Long = 0 @@ -69,15 +68,16 @@ class ActivitiesFragment : private var actionListener: ActivitiesContract.ActionListener? = null override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { - _binding = FragmentActivitiesBinding.inflate(inflater, container, false) + binding = FragmentActivitiesBinding.inflate(inflater, container, false) + val binding = binding!! return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) actionListener = ActivitiesPresenter(activitiesRepository, filesRepository, this) - viewThemeUtils.androidx.themeSwipeRefreshLayout(binding.swipeContainingList) - binding.swipeContainingList.setOnRefreshListener { + binding?.swipeContainingList?.let { viewThemeUtils.androidx.themeSwipeRefreshLayout(it) } + binding?.swipeContainingList?.setOnRefreshListener { lastGiven = ActivitiesContract.ActionListener.UNDEFINED.toLong() actionListener?.loadActivities(lifecycleScope, lastGiven) } @@ -85,8 +85,7 @@ class ActivitiesFragment : } private fun setupContent() { - binding.emptyList.emptyListIcon.setImageResource(R.drawable.ic_activity) - + binding?.emptyList?.emptyListIcon?.setImageResource(R.drawable.ic_activity) adapter = ActivityListAdapter( requireActivity(), userAccountManager, @@ -94,14 +93,12 @@ class ActivitiesFragment : false, viewThemeUtils ) - binding.list.adapter = adapter - + binding?.list?.adapter = adapter val layoutManager = LinearLayoutManager(requireContext()) - binding.list.run { + binding?.list?.run { setLayoutManager(layoutManager) addOnScrollListener(getOnScrollListener(layoutManager)) } - actionListener?.loadActivities(lifecycleScope, ActivitiesContract.ActionListener.UNDEFINED.toLong()) } @@ -138,6 +135,7 @@ class ActivitiesFragment : } override fun showActivities(activities: List, client: NextcloudClient, lastGiven: Long) { + val binding = binding ?: return val clear = this.lastGiven == ActivitiesContract.ActionListener.UNDEFINED.toLong() adapter?.setActivityItems(activities, client, clear) this.lastGiven = lastGiven @@ -157,6 +155,7 @@ class ActivitiesFragment : } override fun showActivitiesLoadError(error: String) { + val binding = binding ?: return connectivityService.isNetworkAndServerAvailable { if (it) { DisplayUtils.showSnackMessage(requireView(), error) @@ -192,11 +191,11 @@ class ActivitiesFragment : } override fun showLoadingMessage() { - binding.emptyList.emptyListView.visibility = View.GONE + binding?.emptyList?.emptyListView?.visibility = View.GONE } override fun showEmptyContent(headline: String, message: String) { - binding.run { + binding?.run { emptyList.emptyListViewHeadline.text = headline emptyList.emptyListViewText.text = message loadingContent.visibility = View.GONE @@ -208,6 +207,7 @@ class ActivitiesFragment : } override fun setProgressIndicatorState(isActive: Boolean) { + val binding = binding ?: return isLoadingActivities = isActive if (adapter?.isEmpty() == false) { binding.swipeContainingList.post { binding.swipeContainingList.isRefreshing = isActive } @@ -216,6 +216,6 @@ class ActivitiesFragment : override fun onDestroyView() { super.onDestroyView() - _binding = null + binding = null } } diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/community/CommunityFragment.kt b/app/src/main/java/com/owncloud/android/ui/fragment/community/CommunityFragment.kt index 78fdf5933496..75c3ec511503 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/community/CommunityFragment.kt +++ b/app/src/main/java/com/owncloud/android/ui/fragment/community/CommunityFragment.kt @@ -22,20 +22,20 @@ import javax.inject.Inject class CommunityFragment : Fragment() { - private var _binding: FragmentCommunityBinding? = null - private val binding get() = _binding!! + private var binding: FragmentCommunityBinding? = null @Inject lateinit var viewThemeUtils: ViewThemeUtils override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { - _binding = FragmentCommunityBinding.inflate(inflater, container, false) + binding = FragmentCommunityBinding.inflate(inflater, container, false) + val binding = binding!! return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - binding.communityReleaseCandidateText.movementMethod = LinkMovementMethod.getInstance() + binding?.communityReleaseCandidateText?.movementMethod = LinkMovementMethod.getInstance() setupViews() setOnClickListeners() } @@ -49,7 +49,7 @@ class CommunityFragment : Fragment() { val contributingLink = getString(R.string.contributing_link) listOf( - binding.communityContributeForumText to + binding?.communityContributeForumText to "${getString(R.string.community_contribute_forum_text)} " + getString( R.string.community_contribute_forum_text_link, @@ -58,7 +58,7 @@ class CommunityFragment : Fragment() { forum ), - binding.communityContributeTranslateText to + binding?.communityContributeTranslateText to getString( R.string.community_contribute_translate_link, primaryColor, @@ -66,7 +66,7 @@ class CommunityFragment : Fragment() { translate ) + " " + getString(R.string.community_contribute_translate_text), - binding.communityContributeGithubText to + binding?.communityContributeGithubText to getString( R.string.community_contribute_github_text, getString( @@ -76,11 +76,11 @@ class CommunityFragment : Fragment() { ) ) ).forEach { (view, content) -> - view.setHtmlContent(content) + view?.setHtmlContent(content) } - viewThemeUtils.material.colorMaterialButtonPrimaryFilled(binding.communityTestingReport) - binding.communityTestingReport.setOnClickListener { + binding?.communityTestingReport?.let { viewThemeUtils.material.colorMaterialButtonPrimaryFilled(it) } + binding?.communityTestingReport?.setOnClickListener { DisplayUtils.startLinkIntent(requireActivity(), R.string.report_issue_empty_link) } } @@ -89,12 +89,12 @@ class CommunityFragment : Fragment() { val activity = requireActivity() listOf( - binding.communityBetaFdroid to R.string.fdroid_beta_link, - binding.communityReleaseCandidateFdroid to R.string.fdroid_link, - binding.communityReleaseCandidatePlaystore to R.string.play_store_register_beta, - binding.communityBetaApk to R.string.beta_apk_link + binding?.communityBetaFdroid to R.string.fdroid_beta_link, + binding?.communityReleaseCandidateFdroid to R.string.fdroid_link, + binding?.communityReleaseCandidatePlaystore to R.string.play_store_register_beta, + binding?.communityBetaApk to R.string.beta_apk_link ).forEach { (view, linkRes) -> - view.setOnClickListener { + view?.setOnClickListener { DisplayUtils.startLinkIntent(activity, linkRes) } } @@ -102,6 +102,6 @@ class CommunityFragment : Fragment() { override fun onDestroyView() { super.onDestroyView() - _binding = null + binding = null } } diff --git a/app/src/main/java/com/owncloud/android/ui/navigation/Navigator.kt b/app/src/main/java/com/owncloud/android/ui/navigation/Navigator.kt index 01ba37b32ba7..99d2650e4bea 100644 --- a/app/src/main/java/com/owncloud/android/ui/navigation/Navigator.kt +++ b/app/src/main/java/com/owncloud/android/ui/navigation/Navigator.kt @@ -38,4 +38,11 @@ class Navigator(private val fragmentManager: FragmentManager, private val fragme fragmentManager.popBackStack() return stack.lastOrNull() } + + fun getTopScreen(): NavigatorScreen? { + val topTag = fragmentManager + .getBackStackEntryAt(fragmentManager.backStackEntryCount - 1) + .name + return NavigatorScreen.fromTag(topTag) + } } diff --git a/app/src/main/java/com/owncloud/android/ui/navigation/NavigatorActivity.kt b/app/src/main/java/com/owncloud/android/ui/navigation/NavigatorActivity.kt index 69ff8c4f7f6c..0612469e2dbc 100644 --- a/app/src/main/java/com/owncloud/android/ui/navigation/NavigatorActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/navigation/NavigatorActivity.kt @@ -12,6 +12,7 @@ import android.content.Intent import android.os.Bundle import android.view.MenuItem import androidx.activity.OnBackPressedCallback +import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentContainerView import com.nextcloud.utils.extensions.getParcelableArgument import com.owncloud.android.R @@ -22,6 +23,7 @@ class NavigatorActivity : DrawerActivity() { private lateinit var navigator: Navigator + // region Lifecycle Methods override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_navigator) @@ -29,14 +31,42 @@ class NavigatorActivity : DrawerActivity() { val screen = intent.getParcelableArgument(EXTRA_SCREEN, NavigatorScreen::class.java) ?: return val fragmentContainerView = findViewById(R.id.fragment_container_view) navigator = Navigator(supportFragmentManager, fragmentContainerView) - setupBackPressedHandler() - push(screen) - supportFragmentManager.addFragmentOnAttachListener { _, fragment -> - AndroidSupportInjection.inject(fragment) + pushOrRestoreScreen(savedInstanceState, screen) + } + + // addFragmentOnAttachListener or via registerFragmentLifecycleCallbacks not providing same result + @Suppress("DEPRECATION") + @Deprecated("Deprecated in Java") + override fun onAttachFragment(fragment: Fragment) { + AndroidSupportInjection.inject(fragment) + super.onAttachFragment(fragment) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + if (item.itemId == android.R.id.home) { + if (isDrawerOpen) { + closeDrawer() + } else { + openDrawer() + } + return true } + return super.onOptionsItemSelected(item) + } + + override fun getMenuItemId(): Int { + val screen = intent.getParcelableArgument(EXTRA_SCREEN, NavigatorScreen::class.java) + return screen?.menuItemId() ?: super.getMenuItemId() + } + + override fun onResume() { + super.onResume() + highlightOrRestoreNavigationViewItem() } + // endregion + // region Public Methods fun pop() { val previousScreen = navigator.pop() ?: return setupActionBar(previousScreen) @@ -46,6 +76,18 @@ class NavigatorActivity : DrawerActivity() { setupActionBar(screen) navigator.push(screen) } + // endregion + + // region Private Methods + private fun pushOrRestoreScreen(savedInstanceState: Bundle?, screen: NavigatorScreen) { + if (savedInstanceState == null) { + push(screen) + } else { + val currentScreen = navigator.getTopScreen() ?: screen + setupActionBar(currentScreen) + highlightNavigationViewItem(currentScreen.menuItemId()) + } + } private fun setupActionBar(screen: NavigatorScreen) { val (style, titleId) = screen.actionBarStyle() @@ -73,27 +115,15 @@ class NavigatorActivity : DrawerActivity() { ) } - override fun onOptionsItemSelected(item: MenuItem): Boolean { - if (item.itemId == android.R.id.home) { - if (isDrawerOpen) { - closeDrawer() - } else { - openDrawer() - } - return true + private fun highlightOrRestoreNavigationViewItem() { + val currentScreen = navigator.getTopScreen() + if (currentScreen != null) { + highlightNavigationViewItem(currentScreen.menuItemId()) + } else { + highlightNavigationViewItem(menuItemId) } - return super.onOptionsItemSelected(item) - } - - override fun getMenuItemId(): Int { - val screen = intent.getParcelableArgument(EXTRA_SCREEN, NavigatorScreen::class.java) - return screen?.menuItemId() ?: super.getMenuItemId() - } - - override fun onResume() { - super.onResume() - highlightNavigationViewItem(menuItemId) } + // endregion companion object { const val EXTRA_SCREEN = "extra_screen" diff --git a/app/src/main/java/com/owncloud/android/ui/navigation/NavigatorScreen.kt b/app/src/main/java/com/owncloud/android/ui/navigation/NavigatorScreen.kt index a1bfccafaf1e..90a0601d21b7 100644 --- a/app/src/main/java/com/owncloud/android/ui/navigation/NavigatorScreen.kt +++ b/app/src/main/java/com/owncloud/android/ui/navigation/NavigatorScreen.kt @@ -17,10 +17,21 @@ import kotlinx.parcelize.Parcelize sealed class NavigatorScreen(val tag: String) : Parcelable { @Parcelize - object Activities : NavigatorScreen("Activities") + object Activities : NavigatorScreen(ACTIVITIES_TAG) @Parcelize - object Community : NavigatorScreen("Community") + object Community : NavigatorScreen(COMMUNITY_TAG) + + companion object { + private const val ACTIVITIES_TAG = "Activities" + private const val COMMUNITY_TAG = "Community" + + fun fromTag(tag: String?): NavigatorScreen? = when (tag) { + ACTIVITIES_TAG -> Activities + COMMUNITY_TAG -> Community + else -> null + } + } fun menuItemId(): Int = when (this) { Community -> R.id.nav_community