Refactoring, using view binding in all fragments, app now targets API 29, replaced deprecated support library PreferenceManager and Custom Tabs with AndroidX equivalents, version bump to 2.3.3

This commit is contained in:
Deniz Düzgören
2019-10-12 21:03:34 +02:00
parent f5666a20c6
commit 37cf130ba0
27 changed files with 827 additions and 801 deletions
@@ -9,7 +9,7 @@ import android.content.Intent
import android.content.SharedPreferences
import android.os.Build
import android.os.Bundle
import android.preference.PreferenceManager
import androidx.preference.PreferenceManager
import android.view.*
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
@@ -20,7 +20,6 @@ import androidx.core.widget.NestedScrollView
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction
import androidx.recyclerview.widget.RecyclerView
import com.crashlytics.android.Crashlytics
import com.denizd.substitutionplan.data.HelperFunctions
import com.denizd.substitutionplan.R
import com.denizd.substitutionplan.fragments.FoodFragment
@@ -33,6 +32,7 @@ import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.android.material.snackbar.Snackbar
import com.google.firebase.FirebaseApp
import java.lang.IllegalArgumentException
import java.lang.NullPointerException
import java.util.*
/**
@@ -49,173 +49,166 @@ internal class Main : AppCompatActivity(R.layout.app_bar_main) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
context = this
// prefs = PreferenceManager.getDefaultSharedPreferences(context)
prefs = PreferenceManager.getDefaultSharedPreferences(context)
val edit = prefs.edit()
val firstTime = Intent(context, FirstTime::class.java)
val login = Intent(context, Login::class.java)
Crashlytics.setUserIdentifier(prefs.getString("username", "") ?: "")
/**
* This cascade of if-else's allows the user to return to any point of the setup if they
* This when-cascade allows the user to return to any point of the setup if they
* decide to postpone it, e.g. logging in but not setting up their preferences. Furthermore,
* it prevents existing users from upgrading from a previous version of the app and skip the
* mandatory login
*/
if (!prefs.getBoolean("successful_login", false)) {
startActivity(login)
finish()
} else if (prefs.getBoolean("firstTime", true)) {
startActivity(firstTime)
finish()
} else {
if (!prefs.getBoolean("colourTransferred", false)) {
HelperFunctions.transferOldColourIntsToString(prefs)
edit.putBoolean("colourTransferred", true).apply()
when {
!prefs.getBoolean("successful_login", false) -> { // launch the login screen
startActivity(Intent(context, Login::class.java))
finish()
}
edit.putInt("launchDev", prefs.getInt("launchDev", 0) + 1)
edit.apply()
FirebaseApp.initializeApp(this)
pingFirebaseTopics()
val appBarLayout = findViewById<AppBarLayout>(R.id.appbarlayout)
val toolbarTxt = findViewById<TextView>(R.id.toolbarTxt)
val bottomNav = findViewById<BottomNavigationView>(R.id.bottom_nav)
val contextView = findViewById<View>(R.id.coordination)
val window = this.window
/// Sets the theme explicitly to dismiss the splash screen
setTheme(R.style.AppTheme0)
/// Sets the system bar's colours according to the current Android version
val barColour = when {
Build.VERSION.SDK_INT < Build.VERSION_CODES.M -> ContextCompat.getColor(context, R.color.legacyBlack)
Build.VERSION.SDK_INT <= Build.VERSION_CODES.P -> ContextCompat.getColor(context, R.color.colorBackground)
else -> 0
}
if (barColour != 0) {
window.navigationBarColor = barColour
window.statusBarColor = barColour
prefs.getBoolean("firstTime", true) -> { // launch the first time setup screen
startActivity(Intent(context, FirstTime::class.java))
finish()
}
else -> { // launch the app
/// Applies theming with additional workarounds for API levels 23-28 (M-P)
when (prefs.getInt("themeInt", 0)) {
0 -> {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
if (Build.VERSION.SDK_INT in 23..28) {
@SuppressLint("InlinedApi")
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
if (!prefs.getBoolean("colourTransferred", false)) {
HelperFunctions.transferOldColourIntsToString(prefs)
edit.putBoolean("colourTransferred", true).apply()
}
edit.putInt("launchDev", prefs.getInt("launchDev", 0) + 1)
edit.apply()
FirebaseApp.initializeApp(this)
pingFirebaseTopics()
val appBarLayout = findViewById<AppBarLayout>(R.id.appbarlayout)
val toolbarTxt = findViewById<TextView>(R.id.toolbarTxt)
val bottomNav = findViewById<BottomNavigationView>(R.id.bottom_nav)
val contextView = findViewById<View>(R.id.coordination)
val window = this.window
/// Sets the theme explicitly to dismiss the splash screen
setTheme(R.style.AppTheme0)
/// Sets the system bar's colours according to the current Android version
val barColour = when {
Build.VERSION.SDK_INT < Build.VERSION_CODES.M -> ContextCompat.getColor(context, R.color.legacyBlack)
Build.VERSION.SDK_INT <= Build.VERSION_CODES.P -> ContextCompat.getColor(context, R.color.colorBackground)
else -> 0
}
if (barColour != 0) {
window.navigationBarColor = barColour
window.statusBarColor = barColour
}
/// Applies theming with additional workarounds for API levels 23-28 (M-P)
when (prefs.getInt("themeInt", 0)) {
0 -> {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
if (Build.VERSION.SDK_INT in 23..28) {
@SuppressLint("InlinedApi")
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
}
}
2 -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
else -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
}
/// Displays the date and time of the last refresh of the substitution plan in a snack bar
if (!prefs.getBoolean("autoRefresh", false) && prefs.getInt("firstTimeOpening", 0) != 0) {
try {
Snackbar.make(contextView, "${getString(R.string.last_updated)} ${prefs.getString("timeNew", "")}", Snackbar.LENGTH_LONG).show()
} catch (e: IllegalArgumentException) {
}
}
2 -> {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
}
else -> {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
}
}
/// Displays the date and time of the last refresh of the substitution plan in a snack bar
if (!prefs.getBoolean("autoRefresh", false) && prefs.getInt("firstTimeOpening", 0) != 0) {
try {
Snackbar.make(contextView, "${getString(R.string.last_updated)} ${prefs.getString("timeNew", "")}", Snackbar.LENGTH_LONG).show()
} catch (e: IllegalArgumentException) {}
}
/**
* Retrieves the greeting string if enabled by the user, sets it empty otherwise.
* Don't set the text view of the greeting string to View.GONE, as that will mess
* with the constraints
*/
val textViewGreeting = findViewById<TextView>(R.id.text_greeting)
textViewGreeting.text = if (prefs.getBoolean("greeting", true) && (prefs.getString("username", "") ?: "").isNotEmpty()) {
getGreetingString()
} else {
""
}
/// Legacy function
if (prefs.getInt("firstTimeOpening", 0) == 0) {
edit.putInt("firstTimeOpening", prefs.getInt("firstTimeOpening", 0) + 1).apply()
}
/// Launch the user-specified fragment (general or personal plan)
val defaultFragment = if (prefs.getBoolean("defaultPersonalised", false)) {
bottomNav.selectedItemId = R.id.personal
toolbarTxt.text = personalPlanTitle()
PersonalPlanFragment()
} else {
bottomNav.selectedItemId = R.id.plan
toolbarTxt.text = getString(R.string.app_name)
GeneralPlanFragment()
}
loadFragment(defaultFragment)
/// Opens the corresponding fragment or the info dialog
bottomNav.setOnNavigationItemSelectedListener { item: MenuItem ->
var fragmentLoading = true
lateinit var fragment: Fragment
when (item.itemId) {
R.id.plan -> {
fragment = GeneralPlanFragment()
toolbarTxt.text = getString(R.string.app_name)
}
R.id.personal -> {
fragment = PersonalPlanFragment()
toolbarTxt.text = personalPlanTitle()
}
R.id.menu -> {
fragment = FoodFragment()
toolbarTxt.text = getString(R.string.food_menu)
}
R.id.openinfopanel -> {
openInfoDialog()
fragmentLoading = false
}
R.id.settings -> {
fragment = SettingsFragment()
toolbarTxt.text = getString(R.string.settings)
}
}
if (fragmentLoading) {
appBarLayout.setExpanded(true)
loadFragment(fragment)
/**
* Retrieves the greeting string if enabled by the user, sets it empty otherwise.
* Don't set the text view of the greeting string to View.GONE, as that will mess
* with the constraints
*/
val textViewGreeting = findViewById<TextView>(R.id.text_greeting)
textViewGreeting.text = if (
prefs.getBoolean("greeting", true)
&& (prefs.getString("username", "") ?: "").isNotEmpty()
) {
getGreetingString()
} else {
false
""
}
}
/// Scrolls to the top of any currently displayed fragment
bottomNav.setOnNavigationItemReselectedListener { item: MenuItem ->
when (item.itemId) {
R.id.plan, R.id.personal -> {
try {
val recyclerView = findViewById<RecyclerView>(R.id.linearRecycler)
recyclerView.post {
recyclerView.smoothScrollToPosition(0)
}
appBarLayout.setExpanded(true)
} catch (e: NullPointerException) {}
/// Legacy function
if (prefs.getInt("firstTimeOpening", 0) == 0) {
edit.putInt("firstTimeOpening", prefs.getInt("firstTimeOpening", 0) + 1).apply()
}
/// Launch the user-specified fragment (general or personal plan)
val defaultFragment = if (prefs.getBoolean("defaultPersonalised", false)) {
bottomNav.selectedItemId = R.id.personal
toolbarTxt.text = personalPlanTitle()
PersonalPlanFragment()
} else {
bottomNav.selectedItemId = R.id.plan
toolbarTxt.text = getString(R.string.app_name)
GeneralPlanFragment()
}
loadFragment(defaultFragment)
/// Opens the corresponding fragment or the info dialog
bottomNav.setOnNavigationItemSelectedListener { item: MenuItem ->
val fragment = when (item.itemId) {
R.id.plan -> {
toolbarTxt.text = getString(R.string.app_name)
GeneralPlanFragment()
}
R.id.personal -> {
toolbarTxt.text = personalPlanTitle()
PersonalPlanFragment()
}
R.id.menu -> {
toolbarTxt.text = getString(R.string.food_menu)
FoodFragment()
}
R.id.openinfopanel -> {
openInfoDialog()
null
}
else -> {
toolbarTxt.text = getString(R.string.settings)
SettingsFragment()
}
}
R.id.menu -> {
try {
val recyclerView = findViewById<RecyclerView>(R.id.linear_food)
recyclerView.post {
recyclerView.smoothScrollToPosition(0)
}
appBarLayout.setExpanded(true)
} catch (e: NullPointerException) {}
if (fragment == null) {
false
} else {
appBarLayout.setExpanded(true)
loadFragment(fragment)
}
R.id.settings -> {
try {
val nsv = findViewById<NestedScrollView>(R.id.nsvsettings)
nsv.post {
nsv.smoothScrollTo(0, 0)
}
/// Scrolls to the top of any currently displayed fragment
bottomNav.setOnNavigationItemReselectedListener { item: MenuItem ->
when (item.itemId) {
R.id.plan, R.id.personal, R.id.menu -> {
try {
val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
recyclerView.post {
recyclerView.smoothScrollToPosition(0)
}
appBarLayout.setExpanded(true)
} catch (e: NullPointerException) {
}
appBarLayout.setExpanded(true)
} catch (e: NullPointerException) {}
}
R.id.settings -> {
try {
val nsv = findViewById<NestedScrollView>(R.id.settings_scroll_view)
nsv.post {
nsv.smoothScrollTo(0, 0)
}
appBarLayout.setExpanded(true)
} catch (e: NullPointerException) {
}
}
}
}
}