diff --git a/.gitignore b/.gitignore index ae7f176..be47ae6 100644 --- a/.gitignore +++ b/.gitignore @@ -89,6 +89,7 @@ gen-external-apklibs .idea/assetWizardSettings.xml .idea/gradle.xml .idea/jarRepositories.xml +.idea/navEditor.xml # Gem/fastlane Gemfile.lock diff --git a/app/build.gradle b/app/build.gradle index abe1b81..22a9a4f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,5 +1,6 @@ apply plugin: 'com.android.application' apply plugin: 'org.jetbrains.kotlin.android' +apply plugin: 'androidx.navigation.safeargs' def relStorePassword = System.getenv("RELEASE_STORE_PASSWORD") def relKeyPassword = System.getenv("RELEASE_KEY_PASSWORD") @@ -49,6 +50,9 @@ dependencies { implementation "androidx.lifecycle:lifecycle-livedata-core:$LIFECYCLE_VERSION" implementation "androidx.lifecycle:lifecycle-viewmodel:$LIFECYCLE_VERSION" implementation 'androidx.recyclerview:recyclerview:1.0.0' + / * Fragment Navigation * / + implementation "androidx.navigation:navigation-fragment-ktx:$NAVIGATION_VERSION" + implementation "androidx.navigation:navigation-ui-ktx:$NAVIGATION_VERSION" / * Unit testing * / testImplementation "junit:junit:$JUNIT_VERSION" androidTestRuntimeOnly "org.jetbrains.kotlin:kotlin-test-junit:$KOTLIN_VERSION" diff --git a/app/src/main/java/com/appttude/h_mal/farmr/ui/FilterDataFragment.kt b/app/src/main/java/com/appttude/h_mal/farmr/ui/FilterDataFragment.kt index 785ca82..1b596ee 100644 --- a/app/src/main/java/com/appttude/h_mal/farmr/ui/FilterDataFragment.kt +++ b/app/src/main/java/com/appttude/h_mal/farmr/ui/FilterDataFragment.kt @@ -13,6 +13,7 @@ import com.appttude.h_mal.farmr.R import com.appttude.h_mal.farmr.base.BaseFragment import com.appttude.h_mal.farmr.model.ShiftType import com.appttude.h_mal.farmr.model.Success +import com.appttude.h_mal.farmr.utils.goBack import com.appttude.h_mal.farmr.utils.setDatePicker import com.appttude.h_mal.farmr.viewmodel.FilterViewModel @@ -109,6 +110,6 @@ class FilterDataFragment : BaseFragment(R.layout.fragment_filte override fun onSuccess(data: Any?) { super.onSuccess(data) - if (data is Success) popBackStack() + if (data is Success) goBack() } } \ No newline at end of file diff --git a/app/src/main/java/com/appttude/h_mal/farmr/ui/FragmentAddItem.kt b/app/src/main/java/com/appttude/h_mal/farmr/ui/FragmentAddItem.kt index 2ab0a89..a3ed587 100644 --- a/app/src/main/java/com/appttude/h_mal/farmr/ui/FragmentAddItem.kt +++ b/app/src/main/java/com/appttude/h_mal/farmr/ui/FragmentAddItem.kt @@ -1,6 +1,7 @@ package com.appttude.h_mal.farmr.ui import android.os.Bundle +import android.util.Log import android.view.View import android.view.ViewGroup import android.widget.Button @@ -10,9 +11,9 @@ import android.widget.RadioButton import android.widget.RadioGroup import android.widget.ScrollView import android.widget.TextView +import androidx.activity.OnBackPressedCallback import androidx.core.widget.doAfterTextChanged import com.appttude.h_mal.farmr.R -import com.appttude.h_mal.farmr.base.BackPressedListener import com.appttude.h_mal.farmr.base.FormFragment import com.appttude.h_mal.farmr.model.ShiftType import com.appttude.h_mal.farmr.model.Success @@ -21,8 +22,8 @@ import com.appttude.h_mal.farmr.utils.createDialog import com.appttude.h_mal.farmr.utils.displayToast import com.appttude.h_mal.farmr.utils.formatAsCurrencyString import com.appttude.h_mal.farmr.utils.formatToTwoDpString +import com.appttude.h_mal.farmr.utils.goBack import com.appttude.h_mal.farmr.utils.hide -import com.appttude.h_mal.farmr.utils.popBackStack import com.appttude.h_mal.farmr.utils.setDatePicker import com.appttude.h_mal.farmr.utils.setTimePicker import com.appttude.h_mal.farmr.utils.show @@ -30,7 +31,9 @@ import com.appttude.h_mal.farmr.utils.validateField import com.appttude.h_mal.farmr.viewmodel.SubmissionViewModel class FragmentAddItem : FormFragment(R.layout.fragment_add_item), - RadioGroup.OnCheckedChangeListener, BackPressedListener { + RadioGroup.OnCheckedChangeListener { + + private lateinit var onBackPressed: OnBackPressedCallback private lateinit var mHourlyRadioButton: RadioButton private lateinit var mPieceRadioButton: RadioButton @@ -121,6 +124,13 @@ class FragmentAddItem : FormFragment(R.layout.fragment_add_ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(false) + // This callback is only called when MyFragment is at least started + onBackPressed = object : OnBackPressedCallback(false) { + override fun handleOnBackPressed() { + onBackPressed() + } + } + requireActivity().onBackPressedDispatcher.addCallback(this, onBackPressed) } override fun onResume() { @@ -130,54 +140,65 @@ class FragmentAddItem : FormFragment(R.layout.fragment_add_ else -> getString(R.string.add_item_title) } setTitle(title) + + onBackPressed.isEnabled = true + } + + override fun onPause() { + super.onPause() + onBackPressed.isEnabled = false } private fun setupViewAfterViewCreated() { - id = arguments?.getLong(ID) + val id = try { + FragmentAddItemArgs.fromBundle(requireArguments()).shiftId + } catch (e: Exception) { + Log.i("Nav Args", "Failed to retrieve args from navigation") + null + } + wholeView.hide() - if (arguments?.containsKey(ID) == true) { - // Since we are editing a shift lets load the shift data into the views - viewModel.getCurrentShift(arguments!!.getLong(ID))?.run { - mLocationEditText.setText(description) - mDateEditText.setText(date) + // Since we are editing a shift lets load the shift data into the views + id?.let { viewModel.getCurrentShift(id) }?.run { + mLocationEditText.setText(description) + mDateEditText.setText(date) - // Set types - mType = ShiftType.getEnumByType(type) - mDescription = description - mDate = date - mPayRate = rateOfPay + // Set types + mType = ShiftType.getEnumByType(type) + mDescription = description + mDate = date + mPayRate = rateOfPay - when (ShiftType.getEnumByType(type)) { - ShiftType.HOURLY -> { - mHourlyRadioButton.isChecked = true - mPieceRadioButton.isChecked = false - mTimeInEditText.setText(timeIn) - mTimeOutEditText.setText(timeOut) - mBreakEditText.setText(breakMins.toString()) - val durationText = "${duration.formatToTwoDpString()} Hours" - mDurationTextView.text = durationText + when (ShiftType.getEnumByType(type)) { + ShiftType.HOURLY -> { + mHourlyRadioButton.isChecked = true + mPieceRadioButton.isChecked = false + mTimeInEditText.setText(timeIn) + mTimeOutEditText.setText(timeOut) + mBreakEditText.setText(breakMins.toString()) + val durationText = "${duration.formatToTwoDpString()} Hours" + mDurationTextView.text = durationText - // Set fields - mTimeIn = timeIn - mTimeOut = timeOut - mBreaks = breakMins - } - - ShiftType.PIECE -> { - mHourlyRadioButton.isChecked = false - mPieceRadioButton.isChecked = true - mUnitEditText.setText(units.formatToTwoDpString()) - - // Set piece rate units - mUnits = units - } + // Set fields + mTimeIn = timeIn + mTimeOut = timeOut + mBreaks = breakMins } - mPayRateEditText.setText(rateOfPay.formatAsCurrencyString()) - mTotalPayTextView.text = totalPay.formatAsCurrencyString() - calculateTotalPay() + ShiftType.PIECE -> { + mHourlyRadioButton.isChecked = false + mPieceRadioButton.isChecked = true + mUnitEditText.setText(units.formatToTwoDpString()) + + // Set piece rate units + mUnits = units + } } + mPayRateEditText.setText(rateOfPay.formatAsCurrencyString()) + mTotalPayTextView.text = totalPay.formatAsCurrencyString() + + calculateTotalPay() } applyFormListener(view = view as ViewGroup) @@ -282,27 +303,26 @@ class FragmentAddItem : FormFragment(R.layout.fragment_add_ } } - override fun onBackPressed(): Boolean { + fun onBackPressed() { if (didFormChange()) { requireContext().createDialog( title = "Discard Changes?", message = "Are you sure you want to discard changes?", displayCancel = true, okCallback = { _, _ -> - mActivity?.popBackStack() + goBack() } ) } else { - mActivity?.popBackStack() + goBack() } - return true } override fun onSuccess(data: Any?) { super.onSuccess(data) if (data is Success) { displayToast(data.successMessage) - popBackStack() + goBack() } } } \ No newline at end of file diff --git a/app/src/main/java/com/appttude/h_mal/farmr/ui/FragmentMain.kt b/app/src/main/java/com/appttude/h_mal/farmr/ui/FragmentMain.kt index 4cc3d54..1fbe573 100644 --- a/app/src/main/java/com/appttude/h_mal/farmr/ui/FragmentMain.kt +++ b/app/src/main/java/com/appttude/h_mal/farmr/ui/FragmentMain.kt @@ -7,11 +7,10 @@ import android.view.Menu import android.view.MenuInflater import android.view.MenuItem import android.view.View +import androidx.activity.OnBackPressedCallback import androidx.core.content.FileProvider import androidx.recyclerview.widget.RecyclerView -import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver import com.appttude.h_mal.farmr.R -import com.appttude.h_mal.farmr.base.BackPressedListener import com.appttude.h_mal.farmr.base.BaseFragment import com.appttude.h_mal.farmr.data.legacydb.ShiftObject import com.appttude.h_mal.farmr.model.Order @@ -19,29 +18,43 @@ import com.appttude.h_mal.farmr.model.Sortable import com.appttude.h_mal.farmr.model.Success import com.appttude.h_mal.farmr.utils.createDialog import com.appttude.h_mal.farmr.utils.displayToast -import com.appttude.h_mal.farmr.utils.hide -import com.appttude.h_mal.farmr.utils.navigateToFragment -import com.appttude.h_mal.farmr.utils.show +import com.appttude.h_mal.farmr.utils.navigateTo import com.appttude.h_mal.farmr.viewmodel.MainViewModel import com.google.android.material.floatingactionbutton.FloatingActionButton import java.io.File import kotlin.system.exitProcess -class FragmentMain : BaseFragment(R.layout.fragment_main), BackPressedListener { +class FragmentMain : BaseFragment(R.layout.fragment_main) { private lateinit var productListView: RecyclerView private lateinit var emptyView: View private lateinit var mAdapter: ShiftListAdapter + private lateinit var onBackPressed: OnBackPressedCallback + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Inflate the layout for this fragment setHasOptionsMenu(true) + // This callback is only called when MyFragment is at least started + onBackPressed = object : OnBackPressedCallback(false) { + override fun handleOnBackPressed() { + onBackPressed() + } + } + requireActivity().onBackPressedDispatcher.addCallback(this, onBackPressed) } override fun onResume() { super.onResume() setTitle("Shift List") + + onBackPressed.isEnabled = true + } + + override fun onPause() { + super.onPause() + onBackPressed.isEnabled = false } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -56,7 +69,7 @@ class FragmentMain : BaseFragment(R.layout.fragment_main), BackPr productListView.adapter = mAdapter view.findViewById(R.id.fab1).setOnClickListener { - navigateToFragment(FragmentAddItem(), name = "additem") + navigateTo(R.id.main_to_addItem) } } @@ -98,7 +111,7 @@ class FragmentMain : BaseFragment(R.layout.fragment_main), BackPr } R.id.filter_data -> { - navigateToFragment(FilterDataFragment(), name = "filterdata") + navigateTo(R.id.main_to_filterData) return true } @@ -181,21 +194,13 @@ class FragmentMain : BaseFragment(R.layout.fragment_main), BackPr file ) intent.setDataAndType(excelUri, "application/vnd.ms-excel") - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) startActivity(intent) } } - private fun exportDialog() { - AlertDialog.Builder(context) - .setTitle("Export?") - .setMessage("Exporting current filtered data. Continue?") - .setNegativeButton(android.R.string.cancel, null) - .setPositiveButton(android.R.string.ok) { _, _ -> exportData() }.create().show() - } - - override fun onBackPressed(): Boolean { + fun onBackPressed() { requireContext().createDialog( title = "Leave?", message = "Are you sure you want to exit Farmr?", @@ -209,6 +214,5 @@ class FragmentMain : BaseFragment(R.layout.fragment_main), BackPr exitProcess(0) } ) - return true } } \ No newline at end of file diff --git a/app/src/main/java/com/appttude/h_mal/farmr/ui/FurtherInfoFragment.kt b/app/src/main/java/com/appttude/h_mal/farmr/ui/FurtherInfoFragment.kt index 4c498d7..700016d 100644 --- a/app/src/main/java/com/appttude/h_mal/farmr/ui/FurtherInfoFragment.kt +++ b/app/src/main/java/com/appttude/h_mal/farmr/ui/FurtherInfoFragment.kt @@ -13,6 +13,7 @@ import com.appttude.h_mal.farmr.model.ShiftType import com.appttude.h_mal.farmr.utils.CURRENCY import com.appttude.h_mal.farmr.utils.formatAsCurrencyString import com.appttude.h_mal.farmr.utils.hide +import com.appttude.h_mal.farmr.utils.navigateTo import com.appttude.h_mal.farmr.utils.navigateToFragment import com.appttude.h_mal.farmr.utils.show import com.appttude.h_mal.farmr.viewmodel.InfoViewModel @@ -51,11 +52,14 @@ class FurtherInfoFragment : BaseFragment(R.layout.fragment_futher hourlyDetailHolder = view.findViewById(R.id.details_hourly_details) unitsHolder = view.findViewById(R.id.details_units_holder) + val id = FurtherInfoFragmentArgs.fromBundle(requireArguments()).shiftId + editButton.setOnClickListener { - navigateToFragment(FragmentAddItem(), name = "additem", bundle = arguments!!) + val nav = FurtherInfoFragmentDirections.furtherInfoToAddItem(id) + navigateTo(nav) } - viewModel.retrieveData(arguments) + viewModel.retrieveData(id) } override fun onCreate(savedInstanceState: Bundle?) { diff --git a/app/src/main/java/com/appttude/h_mal/farmr/ui/MainActivity.kt b/app/src/main/java/com/appttude/h_mal/farmr/ui/MainActivity.kt index bd3e86a..9f0357b 100644 --- a/app/src/main/java/com/appttude/h_mal/farmr/ui/MainActivity.kt +++ b/app/src/main/java/com/appttude/h_mal/farmr/ui/MainActivity.kt @@ -1,14 +1,15 @@ package com.appttude.h_mal.farmr.ui import android.os.Bundle +import android.view.MenuItem import androidx.appcompat.widget.Toolbar +import androidx.navigation.fragment.NavHostFragment import com.appttude.h_mal.farmr.R -import com.appttude.h_mal.farmr.base.BackPressedListener import com.appttude.h_mal.farmr.base.BaseActivity -import com.appttude.h_mal.farmr.utils.popBackStack class MainActivity : BaseActivity() { private lateinit var toolbar: Toolbar + private lateinit var navHost: NavHostFragment override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -16,20 +17,19 @@ class MainActivity : BaseActivity() { toolbar = findViewById(R.id.toolbar) setSupportActionBar(toolbar) - val fragmentTransaction = supportFragmentManager.beginTransaction() - fragmentTransaction.replace(R.id.container, FragmentMain()).addToBackStack("main").commit() + navHost = supportFragmentManager + .findFragmentById(R.id.container) as NavHostFragment + val navController = navHost.navController + navController.setGraph(R.navigation.shift_navigation) } - override fun onBackPressed() { - val currentFragment = supportFragmentManager.findFragmentById(R.id.container) - if (currentFragment is BackPressedListener) { - currentFragment.onBackPressed() - } else { - if (supportFragmentManager.backStackEntryCount > 1) { - popBackStack() - } else { - super.onBackPressed() - } + override fun onOptionsItemSelected(item: MenuItem): Boolean { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + when (item.itemId) { + android.R.id.home -> onBackPressed() } + return super.onOptionsItemSelected(item) } } \ No newline at end of file diff --git a/app/src/main/java/com/appttude/h_mal/farmr/ui/ShiftListAdapter.kt b/app/src/main/java/com/appttude/h_mal/farmr/ui/ShiftListAdapter.kt index 82d8d52..dfe40ce 100644 --- a/app/src/main/java/com/appttude/h_mal/farmr/ui/ShiftListAdapter.kt +++ b/app/src/main/java/com/appttude/h_mal/farmr/ui/ShiftListAdapter.kt @@ -14,6 +14,9 @@ import com.appttude.h_mal.farmr.data.legacydb.ShiftObject import com.appttude.h_mal.farmr.model.ShiftType import com.appttude.h_mal.farmr.utils.ID import com.appttude.h_mal.farmr.utils.formatToTwoDpString +import com.appttude.h_mal.farmr.utils.formatToTwoDp +import com.appttude.h_mal.farmr.utils.generateView +import com.appttude.h_mal.farmr.utils.navigateTo import com.appttude.h_mal.farmr.utils.navigateToFragment class ShiftListAdapter( @@ -64,23 +67,16 @@ class ShiftListAdapter( } } - val b: Bundle = Bundle() - b.putLong(ID, data.id) + view.setOnClickListener { // Navigate to further info - fragment.navigateToFragment( - FurtherInfoFragment(), - bundle = b, - name = "furtherinfo" - ) + val nav = FragmentMainDirections.mainToFurtherInfo(data.id) + fragment.navigateTo(nav) } editView.setOnClickListener { // Navigate to edit - fragment.navigateToFragment( - FragmentAddItem(), - bundle = b, - name = "additem" - ) + val nav = FragmentMainDirections.mainToAddItem(data.id) + fragment.navigateTo(nav) } view.setOnLongClickListener { AlertDialog.Builder(it.context) diff --git a/app/src/main/java/com/appttude/h_mal/farmr/utils/Constants.kt b/app/src/main/java/com/appttude/h_mal/farmr/utils/Constants.kt index 59f48f8..fc14614 100644 --- a/app/src/main/java/com/appttude/h_mal/farmr/utils/Constants.kt +++ b/app/src/main/java/com/appttude/h_mal/farmr/utils/Constants.kt @@ -4,4 +4,5 @@ const val LEGACY = "LEGACY_" const val DATE_FORMAT = "yyyy-MM-dd" const val TIME_FORMAT = "hh:mm" const val ID = "ID" +const val SHIFT_ID = "shiftId" const val CURRENCY = "£" \ No newline at end of file diff --git a/app/src/main/java/com/appttude/h_mal/farmr/utils/NavigationUtils.kt b/app/src/main/java/com/appttude/h_mal/farmr/utils/NavigationUtils.kt new file mode 100644 index 0000000..7193e42 --- /dev/null +++ b/app/src/main/java/com/appttude/h_mal/farmr/utils/NavigationUtils.kt @@ -0,0 +1,32 @@ +package com.appttude.h_mal.farmr.utils + +import android.view.View +import androidx.fragment.app.Fragment +import androidx.navigation.NavDirections +import androidx.navigation.Navigation +import com.appttude.h_mal.farmr.R + +fun Fragment.navigateToFragment(newFragment: Fragment) { + childFragmentManager.beginTransaction() + .add(R.id.container, newFragment) + .commit() +} + + +fun View.navigateTo(navigationId: Int) { + Navigation.findNavController(this).navigate(navigationId) +} + +fun View.navigateTo(navDirections: NavDirections) { + Navigation.findNavController(this).navigate(navDirections) +} + +fun Fragment.navigateTo(navigationId: Int) { + Navigation.findNavController(requireView()).navigate(navigationId) +} + +fun Fragment.navigateTo(navDirections: NavDirections) { + Navigation.findNavController(requireView()).navigate(navDirections) +} + +fun Fragment.goBack() = Navigation.findNavController(requireView()).popBackStack() \ No newline at end of file diff --git a/app/src/main/java/com/appttude/h_mal/farmr/viewmodel/InfoViewModel.kt b/app/src/main/java/com/appttude/h_mal/farmr/viewmodel/InfoViewModel.kt index 025829e..8692912 100644 --- a/app/src/main/java/com/appttude/h_mal/farmr/viewmodel/InfoViewModel.kt +++ b/app/src/main/java/com/appttude/h_mal/farmr/viewmodel/InfoViewModel.kt @@ -10,13 +10,7 @@ class InfoViewModel( repository: Repository ) : ShiftViewModel(repository) { - fun retrieveData(bundle: Bundle?) { - val id = bundle?.getLong(ID) - if (id == null) { - onError("Failed to retrieve shift") - return - } - + fun retrieveData(id: Long) { val shift = getCurrentShift(id) if (shift == null) { onError("Failed to retrieve shift") diff --git a/app/src/main/res/layout/main_view.xml b/app/src/main/res/layout/main_view.xml index 5dcff32..aef69db 100644 --- a/app/src/main/res/layout/main_view.xml +++ b/app/src/main/res/layout/main_view.xml @@ -32,14 +32,17 @@ - - + app:defaultNavHost="true" + android:id="@+id/container" + tools:layout="@layout/fragment_main"> + \ No newline at end of file diff --git a/app/src/main/res/navigation/shift_navigation.xml b/app/src/main/res/navigation/shift_navigation.xml new file mode 100644 index 0000000..7289dd2 --- /dev/null +++ b/app/src/main/res/navigation/shift_navigation.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/test/java/com/appttude/h_mal/farmr/viewmodel/InfoViewModelTest.kt b/app/src/test/java/com/appttude/h_mal/farmr/viewmodel/InfoViewModelTest.kt index 3fb73c0..443d363 100644 --- a/app/src/test/java/com/appttude/h_mal/farmr/viewmodel/InfoViewModelTest.kt +++ b/app/src/test/java/com/appttude/h_mal/farmr/viewmodel/InfoViewModelTest.kt @@ -17,12 +17,10 @@ class InfoViewModelTest : ShiftViewModelTest() { // Arrange val id = anyLong() val shift = mockk() - val bundle = mockk() // Act every { repository.readSingleShiftFromDatabase(id) }.returns(shift) - every { bundle.getLong(ID) }.returns(id) - viewModel.retrieveData(bundle) + viewModel.retrieveData(id) // Assert assertIs(retrieveCurrentData()) @@ -32,35 +30,14 @@ class InfoViewModelTest : ShiftViewModelTest() { ) } - @Test - fun retrieveData_noValidBundleAndId_unsuccessfulRetrieval() { - // Arrange - val id = anyLong() - val shift = mockk() - val bundle = mockk() - - // Act - every { repository.readSingleShiftFromDatabase(id) }.returns(shift) - every { bundle.getLong(ID) }.returns(id) - viewModel.retrieveData(null) - - // Assert - assertEquals( - retrieveCurrentError(), - "Failed to retrieve shift" - ) - } - @Test fun retrieveData_validBundleNoShift_successfulRetrieval() { // Arrange val id = anyLong() - val bundle = mockk() // Act every { repository.readSingleShiftFromDatabase(id) }.returns(null) - every { bundle.getLong(ID) }.returns(id) - viewModel.retrieveData(bundle) + viewModel.retrieveData(id) // Assert assertEquals( diff --git a/build.gradle b/build.gradle index 4faecfe..12d88d4 100644 --- a/build.gradle +++ b/build.gradle @@ -13,6 +13,7 @@ buildscript { maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } } dependencies { + classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$NAVIGATION_VERSION" classpath "com.android.tools.build:gradle:$GRADLE_PLUGIN_VERSION" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$KOTLIN_VERSION" classpath "com.autonomousapps:dependency-analysis-gradle-plugin:$GRADLE_ANALYZE_VERSION" diff --git a/gradle.properties b/gradle.properties index e3acd5b..30ff04f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,6 +8,7 @@ MATERIAL_VERSION = 1.0.0 CONSTR_LAYOUT_VERSION = 1.1.3 LIFECYCLE_VERSION = 2.5.1 VIEWMODEL_VERSION = 2.4.1 +NAVIGATION_VERSION = 2.3.2 PREFERENCES_VERSION = 1.2.1 MOKITO_INLINE_VERSION = 2.13.0 CORE_TEST_VERSION = 2.1.0