From b6ce29a39dcb3931b30d6a4f80c13c4315aa541f Mon Sep 17 00:00:00 2001 From: Hersh Kumar <56927116+unc0ded@users.noreply.github.com> Date: Mon, 31 May 2021 01:12:44 +0530 Subject: [PATCH] feat: use jetpack navigation for BottomNavigationView --- app/build.gradle.kts | 3 + .../view/activities/MainActivity.kt | 138 +++++++----------- .../view/activities/SettingsActivity.kt | 1 - .../mentorship/view/fragments/HomeFragment.kt | 4 - .../view/fragments/MembersFragment.kt | 7 - .../view/fragments/ProfileFragment.kt | 6 +- .../view/fragments/RelationPagerFragment.kt | 1 - .../view/fragments/RequestsFragment.kt | 7 +- app/src/main/res/layout/activity_main.xml | 5 +- .../main/res/navigation/main_navigation.xml | 45 ++++++ app/src/main/res/values-v21/styles.xml | 7 +- app/src/main/res/values/styles.xml | 7 +- build.gradle.kts | 1 + buildSrc/src/main/kotlin/Dependencies.kt | 4 + 14 files changed, 114 insertions(+), 122 deletions(-) create mode 100644 app/src/main/res/navigation/main_navigation.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a39df83e1..20d85ecd0 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -4,6 +4,7 @@ plugins { kotlin("kapt") id("kotlin-android-extensions") + id("androidx.navigation.safeargs.kotlin") } android { compileSdkVersion(Versions.compileSdkVersion) @@ -82,6 +83,8 @@ dependencies { implementation(Dependencies.fragment_ktx) + implementation(Dependencies.navigation_fragment) + implementation(Dependencies.navigation_ui) implementation(Dependencies.viewPager2) implementation(Dependencies.swipe_refresh_layout) } diff --git a/app/src/main/java/org/systers/mentorship/view/activities/MainActivity.kt b/app/src/main/java/org/systers/mentorship/view/activities/MainActivity.kt index 52170a59b..c6c0af37a 100644 --- a/app/src/main/java/org/systers/mentorship/view/activities/MainActivity.kt +++ b/app/src/main/java/org/systers/mentorship/view/activities/MainActivity.kt @@ -1,27 +1,24 @@ package org.systers.mentorship.view.activities -import android.content.Intent import android.os.Bundle import android.view.Menu import android.view.MenuItem import android.widget.Toast -import com.google.android.material.bottomnavigation.BottomNavigationView +import androidx.activity.OnBackPressedCallback +import androidx.navigation.findNavController +import androidx.navigation.fragment.NavHostFragment +import androidx.navigation.ui.AppBarConfiguration +import androidx.navigation.ui.onNavDestinationSelected +import androidx.navigation.ui.setupWithNavController import kotlinx.android.synthetic.main.activity_main.* import org.systers.mentorship.R import org.systers.mentorship.utils.PreferenceManager -import org.systers.mentorship.view.fragments.HomeFragment -import org.systers.mentorship.view.fragments.MembersFragment -import org.systers.mentorship.view.fragments.ProfileFragment -import org.systers.mentorship.view.fragments.RelationPagerFragment -import org.systers.mentorship.view.fragments.RequestsFragment /** * This activity has the bottom navigation which allows the user to switch between fragments */ class MainActivity : BaseActivity() { - private var atHome = true - private val TOAST_DURATION = 4000 private var mLastPress: Long = 0 private lateinit var exitToast: Toast @@ -32,96 +29,59 @@ class MainActivity : BaseActivity() { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) setSupportActionBar(toolbar) - bottomNavigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener) bottomNavigation.setOnNavigationItemReselectedListener { } - if (savedInstanceState == null) { - showHomeFragment() - } else { - atHome = savedInstanceState.getBoolean("atHome") - } - } + val navHostFragment = + supportFragmentManager.findFragmentById(R.id.contentFrame) as NavHostFragment + val navController = navHostFragment.navController + // Specify top-level destinations + val appBarConfiguration = AppBarConfiguration( + setOf( + R.id.navigation_home, + R.id.navigation_profile, + R.id.navigation_relation, + R.id.navigation_members, + R.id.navigation_requests + ) + ) + // Setup toolbar to automatically show title based on label specified in nav graph + collapsingToolbarLayout.setupWithNavController(toolbar, navController, appBarConfiguration) + // Setup bottom nav to automatically handle navigation based on nav graph and bottom nav menu + bottomNavigation.setupWithNavController(navController) - private val mOnNavigationItemSelectedListener = - BottomNavigationView.OnNavigationItemSelectedListener { item -> - when (item.itemId) { - R.id.navigation_home -> { - replaceFragment(R.id.contentFrame, HomeFragment.newInstance(), - R.string.fragment_title_home) - atHome = true - return@OnNavigationItemSelectedListener true - } - R.id.navigation_profile -> { - replaceFragment(R.id.contentFrame, ProfileFragment.newInstance(), - R.string.fragment_title_profile) - atHome = false - return@OnNavigationItemSelectedListener true - } - R.id.navigation_relation -> { - replaceFragment(R.id.contentFrame, RelationPagerFragment.newInstance(), - R.string.fragment_title_relation) - atHome = false - return@OnNavigationItemSelectedListener true - } - R.id.navigation_members -> { - replaceFragment(R.id.contentFrame, MembersFragment.newInstance(), - R.string.fragment_title_members) - atHome = false - return@OnNavigationItemSelectedListener true - } - R.id.navigation_requests -> { - replaceFragment(R.id.contentFrame, RequestsFragment.newInstance(), - R.string.fragment_title_requests) - atHome = false - return@OnNavigationItemSelectedListener true + onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + if (navController.currentDestination?.id == R.id.navigation_home) { + val currentTime = System.currentTimeMillis() + if (currentTime - mLastPress > TOAST_DURATION) { + exitToast = Toast.makeText( + baseContext, + getString(R.string.exit_toast), + Toast.LENGTH_LONG + ) + exitToast.show() + mLastPress = currentTime + } else { + exitToast.cancel() // Hide toast on App exit + isEnabled = false + onBackPressed() } + } else { + isEnabled = false + onBackPressed() + isEnabled = true } - false } + }) + } override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.main_menu, menu) - return true - } - - override fun onOptionsItemSelected(item: MenuItem) = - when (item.itemId) { - R.id.menu_settings -> { - startActivity(Intent(this, SettingsActivity::class.java)) - true - } - else -> false - } - - private fun showHomeFragment() { - atHome = true - bottomNavigation.selectedItemId = R.id.navigation_home - replaceFragment(R.id.contentFrame, HomeFragment.newInstance(), R.string.fragment_title_home) - } - - override fun onSaveInstanceState(outState: Bundle) { - super.onSaveInstanceState(outState) - - outState.putBoolean("atHome", atHome) - } - - private fun showToast() { - val currentTime = System.currentTimeMillis() - if (currentTime - mLastPress > TOAST_DURATION) { - exitToast = Toast.makeText(baseContext, getString(R.string.exit_toast), Toast.LENGTH_LONG) - exitToast.show() - mLastPress = currentTime - } else { - exitToast.cancel() // Hide toast on App exit - super.onBackPressed() - } + return super.onCreateOptionsMenu(menu) } - override fun onBackPressed() { - if (!atHome) { - showHomeFragment() - } else { - showToast() - } + override fun onOptionsItemSelected(item: MenuItem): Boolean { + val navController = findNavController(R.id.contentFrame) + return item.onNavDestinationSelected(navController) || super.onOptionsItemSelected(item) } } diff --git a/app/src/main/java/org/systers/mentorship/view/activities/SettingsActivity.kt b/app/src/main/java/org/systers/mentorship/view/activities/SettingsActivity.kt index 436ffd847..bcf7b005e 100644 --- a/app/src/main/java/org/systers/mentorship/view/activities/SettingsActivity.kt +++ b/app/src/main/java/org/systers/mentorship/view/activities/SettingsActivity.kt @@ -18,7 +18,6 @@ class SettingsActivity : BaseActivity() { supportActionBar?.title = getString(R.string.settings) supportActionBar?.setDisplayHomeAsUpEnabled(true) - supportActionBar?.setDisplayShowHomeEnabled(true) tvLogout.setOnClickListener { val builder = AlertDialog.Builder(this) diff --git a/app/src/main/java/org/systers/mentorship/view/fragments/HomeFragment.kt b/app/src/main/java/org/systers/mentorship/view/fragments/HomeFragment.kt index 604036f04..5d0d0d4f1 100644 --- a/app/src/main/java/org/systers/mentorship/view/fragments/HomeFragment.kt +++ b/app/src/main/java/org/systers/mentorship/view/fragments/HomeFragment.kt @@ -27,10 +27,6 @@ class HomeFragment : BaseFragment() { private lateinit var achievementsAdapter: AchievementsAdapter companion object { - /** - * Creates an instance of HomeFragment - */ - fun newInstance() = HomeFragment() val TAG: String = HomeFragment::class.java.simpleName } diff --git a/app/src/main/java/org/systers/mentorship/view/fragments/MembersFragment.kt b/app/src/main/java/org/systers/mentorship/view/fragments/MembersFragment.kt index a885d24a0..37a81d821 100644 --- a/app/src/main/java/org/systers/mentorship/view/fragments/MembersFragment.kt +++ b/app/src/main/java/org/systers/mentorship/view/fragments/MembersFragment.kt @@ -38,13 +38,6 @@ import org.systers.mentorship.viewmodels.MembersViewModel */ class MembersFragment : BaseFragment() { - companion object { - /** - * Creates an instance of [MembersFragment] - */ - fun newInstance() = MembersFragment() - } - private var memberListInitialized = false private val membersViewModel: MembersViewModel by viewModels() diff --git a/app/src/main/java/org/systers/mentorship/view/fragments/ProfileFragment.kt b/app/src/main/java/org/systers/mentorship/view/fragments/ProfileFragment.kt index 5a2324597..1631b1d75 100644 --- a/app/src/main/java/org/systers/mentorship/view/fragments/ProfileFragment.kt +++ b/app/src/main/java/org/systers/mentorship/view/fragments/ProfileFragment.kt @@ -21,10 +21,6 @@ import org.systers.mentorship.viewmodels.ProfileViewModel class ProfileFragment : BaseFragment() { companion object { - /** - * Creates an instance of ProfileFragment - */ - fun newInstance() = ProfileFragment() val TAG: String = ProfileFragment::class.java.simpleName } @@ -73,7 +69,7 @@ class ProfileFragment : BaseFragment() { editProfileFragment.setOnDismissListener { fetchNewest() } - fragmentManager?.let { editProfileFragment.show(it, getString(R.string.fragment_title_edit_profile)) } + childFragmentManager.let { editProfileFragment.show(it, getString(R.string.fragment_title_edit_profile)) } } true } diff --git a/app/src/main/java/org/systers/mentorship/view/fragments/RelationPagerFragment.kt b/app/src/main/java/org/systers/mentorship/view/fragments/RelationPagerFragment.kt index a4d49c2eb..f758431e1 100644 --- a/app/src/main/java/org/systers/mentorship/view/fragments/RelationPagerFragment.kt +++ b/app/src/main/java/org/systers/mentorship/view/fragments/RelationPagerFragment.kt @@ -79,7 +79,6 @@ class RelationPagerFragment : BaseFragment() { baseActivity.tlMentorshipRelation.removeAllTabs() tvFindPeopleBtn.setOnClickListener { baseActivity.bottomNavigation.selectedItemId = R.id.navigation_members - baseActivity.replaceFragment(R.id.contentFrame, MembersFragment.newInstance(), R.string.navigation_title_members) } } else { tvNoCurrentRelation.visibility = View.GONE diff --git a/app/src/main/java/org/systers/mentorship/view/fragments/RequestsFragment.kt b/app/src/main/java/org/systers/mentorship/view/fragments/RequestsFragment.kt index 3e38f7572..10e3b9c17 100644 --- a/app/src/main/java/org/systers/mentorship/view/fragments/RequestsFragment.kt +++ b/app/src/main/java/org/systers/mentorship/view/fragments/RequestsFragment.kt @@ -18,12 +18,7 @@ import org.systers.mentorship.viewmodels.RequestsViewModel class RequestsFragment : BaseFragment() { companion object { - /** - * Creates an instance of [RequestsFragment] - */ - fun newInstance() = RequestsFragment() - - val TAG = RelationFragment::class.java.simpleName + val TAG = RequestsFragment::class.java.simpleName } private val requestsViewModel: RequestsViewModel by viewModels() diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 5f2a6f7b6..5671e8256 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -56,7 +56,10 @@ android:fillViewport="true" app:layout_behavior="@string/appbar_scrolling_view_behavior"> - diff --git a/app/src/main/res/navigation/main_navigation.xml b/app/src/main/res/navigation/main_navigation.xml new file mode 100644 index 000000000..82ab7434d --- /dev/null +++ b/app/src/main/res/navigation/main_navigation.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml index 006e4b1ec..b10cb1f11 100644 --- a/app/src/main/res/values-v21/styles.xml +++ b/app/src/main/res/values-v21/styles.xml @@ -11,8 +11,7 @@ true - + - +