Skip to content
This repository has been archived by the owner on Jan 5, 2023. It is now read-only.

I followed rule of 3. #418

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
I followed rule of 3. and apply it on lifecycleScope.launch {repeatOn…
…Lifecycle(Lifecycle.State.STARTED) {}} I found many usage in same level and created ext. fun to handle flow collect operation.
  • Loading branch information
Ahmad Kazimi committed Apr 24, 2022
commit e052e488d3a323b64e1a7807c7d501082df4c408
2 changes: 1 addition & 1 deletion depconstraints/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ val hamcrest = "1.3"
val hilt = Versions.HILT_AGP
val junit = "4.13"
val junitExt = "1.1.1"
val lifecycle = "2.4.0-alpha01"
val lifecycle = "2.4.1"
val lottie = "3.0.0"
val material = "1.4.0-beta01"
val mockito = "3.3.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ import androidx.lifecycle.repeatOnLifecycle
import com.google.samples.apps.iosched.ui.LaunchNavigatonAction.NavigateToMainActivityAction
import com.google.samples.apps.iosched.ui.LaunchNavigatonAction.NavigateToOnboardingAction
import com.google.samples.apps.iosched.ui.onboarding.OnboardingActivity
import com.google.samples.apps.iosched.util.collectLifecycleFlow
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

/**
Expand All @@ -41,20 +41,16 @@ class LauncherActivity : AppCompatActivity() {

val viewModel: LaunchViewModel by viewModels()

lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.launchDestination.collect { action ->
when (action) {
is NavigateToMainActivityAction -> startActivity(
Intent(this@LauncherActivity, MainActivity::class.java)
)
is NavigateToOnboardingAction -> startActivity(
Intent(this@LauncherActivity, OnboardingActivity::class.java)
)
}
finish()
}
collectLifecycleFlow(viewModel.launchDestination) { action ->
when (action) {
is NavigateToMainActivityAction -> startActivity(
Intent(this@LauncherActivity, MainActivity::class.java)
)
is NavigateToOnboardingAction -> startActivity(
Intent(this@LauncherActivity, OnboardingActivity::class.java)
)
}
finish()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isVisible
import androidx.core.view.updatePadding
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.AppBarConfiguration
Expand All @@ -52,11 +49,10 @@ import com.google.samples.apps.iosched.ui.messages.SnackbarMessageManager
import com.google.samples.apps.iosched.ui.signin.SignInDialogFragment
import com.google.samples.apps.iosched.ui.signin.SignOutDialogFragment
import com.google.samples.apps.iosched.util.HeightTopWindowInsetsListener
import com.google.samples.apps.iosched.util.collectLifecycleFlow
import com.google.samples.apps.iosched.util.signin.FirebaseAuthErrorCodeConverter
import com.google.samples.apps.iosched.util.updateForTheme
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import timber.log.Timber
import java.util.UUID
import javax.inject.Inject
Expand Down Expand Up @@ -155,36 +151,20 @@ class MainActivity : AppCompatActivity(), NavigationHost {
navigateTo(requestedNavId)
}

lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
launch {
viewModel.navigationActions.collect { action ->
when (action) {
MainNavigationAction.OpenSignIn -> openSignInDialog()
MainNavigationAction.OpenSignOut -> openSignOutDialog()
}
}
}
launch {
viewModel.theme.collect { theme ->
updateForTheme(theme)
}
}
// AR-related Flows
launch {
viewModel.arCoreAvailability.collect { result ->
// Do nothing - activate flow
Timber.d("ArCoreAvailability = $result")
}
}
launch {
viewModel.pinnedSessionsJson.collect { /* Do nothing - activate flow */ }
}
launch {
viewModel.canSignedInUserDemoAr.collect { /* Do nothing - activate flow */ }
}
collectLifecycleFlow(viewModel.navigationActions) { action ->
when (action) {
MainNavigationAction.OpenSignIn -> openSignInDialog()
MainNavigationAction.OpenSignOut -> openSignOutDialog()
}
}
collectLifecycleFlow(viewModel.navigationActions) { /* Do nothing - activate flow */}
collectLifecycleFlow(viewModel.theme) { /* Do nothing - activate flow */ }
collectLifecycleFlow(viewModel.arCoreAvailability) { result ->
// Do nothing - activate flow
Timber.d("ArCoreAvailability = $result")
}
collectLifecycleFlow(viewModel.pinnedSessionsJson) { /* Do nothing - activate flow */ }
collectLifecycleFlow(viewModel.canSignedInUserDemoAr) { /* Do nothing - activate flow */ }

binding.navigationRail?.let {
ViewCompat.setOnApplyWindowInsetsListener(it) { view, insets ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.RecyclerView
import com.google.samples.apps.iosched.R
import com.google.samples.apps.iosched.util.collectLifecycleFlow
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -61,12 +62,8 @@ class MapVariantSelectionDialogFragment : AppCompatDialogFragment() {
adapter = MapVariantAdapter(::selectMapVariant)
view.findViewById<RecyclerView>(R.id.map_variant_list).adapter = adapter

lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
mapViewModel.mapVariant.collect {
adapter.currentSelection = it
}
}
collectLifecycleFlow(mapViewModel.mapVariant) {
adapter.currentSelection = it
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,12 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.google.samples.apps.iosched.R
import com.google.samples.apps.iosched.shared.util.inTransaction
import com.google.samples.apps.iosched.ui.signin.SignInDialogFragment
import com.google.samples.apps.iosched.util.collectLifecycleFlow
import com.google.samples.apps.iosched.util.doOnApplyWindowInsets
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

@AndroidEntryPoint
class OnboardingActivity : AppCompatActivity() {
Expand All @@ -57,13 +53,9 @@ class OnboardingActivity : AppCompatActivity() {
}
}

lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.navigationActions.collect { action ->
if (action == OnboardingNavigationAction.NavigateToSignInDialog) {
openSignInDialog()
}
}
collectLifecycleFlow(viewModel.navigationActions) { action ->
if (action == OnboardingNavigationAction.NavigateToSignInDialog) {
openSignInDialog()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import androidx.lifecycle.repeatOnLifecycle
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.samples.apps.iosched.R
import com.google.samples.apps.iosched.model.SessionId
import com.google.samples.apps.iosched.util.collectLifecycleFlow
import com.google.samples.apps.iosched.util.makeBold
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collect
Expand Down Expand Up @@ -92,17 +93,13 @@ class RemoveReservationDialogFragment : AppCompatDialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.snackbarMessages.collect {
// Using Toast instead of Snackbar as it's easier for DialogFragment
Toast.makeText(
requireContext(),
it.messageId,
if (it.longDuration) Toast.LENGTH_LONG else Toast.LENGTH_SHORT
).show()
}
}
collectLifecycleFlow(viewModel.snackbarMessages) {
// Using Toast instead of Snackbar as it's easier for DialogFragment
Toast.makeText(
requireContext(),
it.messageId,
if (it.longDuration) Toast.LENGTH_LONG else Toast.LENGTH_SHORT
).show()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,11 @@ import android.widget.ArrayAdapter
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatDialogFragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.samples.apps.iosched.R
import com.google.samples.apps.iosched.model.Theme
import com.google.samples.apps.iosched.util.collectLifecycleFlow
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

@AndroidEntryPoint
class ThemeSettingDialogFragment : AppCompatDialogFragment() {
Expand Down Expand Up @@ -61,26 +57,17 @@ class ThemeSettingDialogFragment : AppCompatDialogFragment() {
super.onCreate(savedInstanceState)

// Note you don't need to use viewLifecycleOwner in DialogFragment.
lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.availableThemes.collect { themes ->
listAdapter.clear()
listAdapter.addAll(
themes.map { theme ->
ThemeHolder(theme, getTitleForTheme(theme))
}
)

updateSelectedItem(viewModel.theme.value)
collectLifecycleFlow(viewModel.availableThemes) { themes ->
listAdapter.clear()
listAdapter.addAll(
themes.map { theme ->
ThemeHolder(theme, getTitleForTheme(theme))
}
}
)
updateSelectedItem(viewModel.theme.value)
}

lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.theme.collect { updateSelectedItem(it) }
}
}
collectLifecycleFlow(viewModel.theme) { updateSelectedItem(it) }
}

private fun updateSelectedItem(selected: Theme?) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import androidx.lifecycle.repeatOnLifecycle
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.samples.apps.iosched.databinding.DialogSignInBinding
import com.google.samples.apps.iosched.ui.signin.SignInNavigationAction.RequestSignIn
import com.google.samples.apps.iosched.util.collectLifecycleFlow
import com.google.samples.apps.iosched.util.executeAfter
import com.google.samples.apps.iosched.util.signin.SignInHandler
import dagger.hilt.android.AndroidEntryPoint
Expand Down Expand Up @@ -69,17 +70,14 @@ class SignInDialogFragment : AppCompatDialogFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
signInViewModel.signInNavigationActions.collect { action ->
if (action == RequestSignIn) {
activity?.startActivityForResult(
signInHandler.makeSignInIntent(),
REQUEST_CODE_SIGN_IN
)
dismiss()
}
}
collectLifecycleFlow(signInViewModel.signInNavigationActions) {
action ->
if (action == RequestSignIn) {
activity?.startActivityForResult(
signInHandler.makeSignInIntent(),
REQUEST_CODE_SIGN_IN
)
dismiss()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.samples.apps.iosched.databinding.DialogSignOutBinding
import com.google.samples.apps.iosched.shared.data.signin.AuthenticatedUserInfo
import com.google.samples.apps.iosched.ui.signin.SignInNavigationAction.RequestSignOut
import com.google.samples.apps.iosched.util.collectLifecycleFlow
import com.google.samples.apps.iosched.util.executeAfter
import com.google.samples.apps.iosched.util.signin.SignInHandler
import dagger.hilt.android.AndroidEntryPoint
Expand Down Expand Up @@ -73,14 +74,10 @@ class SignOutDialogFragment : AppCompatDialogFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
signInViewModel.signInNavigationActions.collect { action ->
if (action == RequestSignOut) {
signInHandler.signOut(requireContext())
dismiss()
}
}
collectLifecycleFlow(signInViewModel.signInNavigationActions) { action ->
if (action == RequestSignOut) {
signInHandler.signOut(requireContext())
dismiss()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,8 @@ import android.content.res.TypedArray
import android.graphics.Typeface
import android.net.wifi.WifiConfiguration
import android.os.Build
import android.text.*
import android.text.Layout.Alignment
import android.text.Spannable
import android.text.SpannableString
import android.text.Spanned
import android.text.StaticLayout
import android.text.TextPaint
import android.text.style.StyleSpan
import android.util.TypedValue
import android.view.View
Expand All @@ -37,16 +33,21 @@ import androidx.annotation.ColorInt
import androidx.annotation.DimenRes
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.appcompat.app.AppCompatDialogFragment
import androidx.core.content.res.ResourcesCompat
import androidx.core.os.BuildCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.databinding.ObservableBoolean
import androidx.databinding.ViewDataBinding
import androidx.drawerlayout.widget.DrawerLayout
import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
import androidx.fragment.app.Fragment
import androidx.lifecycle.*
import com.google.samples.apps.iosched.model.Theme
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.FlowCollector
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch

fun ObservableBoolean.hasSameValue(other: ObservableBoolean) = get() == other.get()

Expand Down Expand Up @@ -326,3 +327,19 @@ fun Context.getColorFromTheme(colorAttributeId: Int): Int {
typedArray.recycle()
return color
}
/** to collect flow in a life cycle scope for [AppCompatActivity] * */
fun <T> AppCompatActivity.collectLifecycleFlow(flow: Flow<T>, collect: FlowCollector<T>) {
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
flow.collect(collect)
}
}
}
/** to collect flow in a life cycle scope for [Fragment] * */
fun <T> Fragment.collectLifecycleFlow(flow: Flow<T>, collect: FlowCollector<T>) {
lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
flow.collect(collect)
}
}
}