I write a code for a simple dice roll app but there is a problem in updating the image of an image view that bound with a binding adapter
I can't extend BaseObservable class because I already extended the ViewModel class. I need that for keeping data after the status changed. Also, I can't observe the live data inside my binding adapter because the function is static
do you know any other way?
This is my xml code
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewModel"
type="com.example.diceroller.MainActivityViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="#+id/imgDice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:imageRes="#{viewModel.drawableResource}" />
<Button
android:id="#+id/btnRoll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
android:text="Roll the dice"
android:onClick="#{() -> viewModel.onRollButtonClicked()}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
and this is my kotlin code
class MainActivityViewModel : ViewModel() , Observable {
#Bindable
var drawableResource : MutableLiveData<Int> = MutableLiveData<Int>()
init {
drawableResource.value = R.drawable.dice_1
}
fun onRollButtonClicked(){
drawableResource.value = when(Random.nextInt(1,7)){
1 -> R.drawable.dice_1
2 -> R.drawable.dice_2
3 -> R.drawable.dice_3
4 -> R.drawable.dice_4
5 -> R.drawable.dice_5
else -> R.drawable.dice_6
}
}
override fun addOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback?) {
}
override fun removeOnPropertyChangedCallback(callback:
Observable.OnPropertyChangedCallback?) {
}
}
#BindingAdapter("android:imageRes")
fun loadImage(view : View , imageRes : Int){
(view as ImageView).setImageResource(imageRes)
}
Related
I have a problem:
I have a TextView whose content is constantly changing via LiveData. This looks all right when the animation isn't executing, but when the MotionLayout starts executing, my text gets blocked a little bit.
And the constraints of my TextView and Button are packed.
activity:
class ErrorActivity : AppCompatActivity() {
private val mViewModel by viewModels<ErrorViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
DataBindingUtil.setContentView<ActivityErrorBinding>(this, R.layout.activity_error).apply {
lifecycleOwner = this#ErrorActivity
viewModel = mViewModel
}
}
fun startStopAnim(v: View) {
mViewModel.anim()
}
}
activity layout:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:binding="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewModel"
type="com.test.test.ErrorViewModel" />
</data>
<androidx.constraintlayout.motion.widget.MotionLayout
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="#xml/scene"
binding:anim="#{viewModel.mAnim}">
<TextView
android:id="#+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{#string/test(viewModel.mCountDown)}"
android:textSize="32sp"
app:layout_constraintEnd_toStartOf="#+id/btn"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="#string/test" />
<Button
android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/tv"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/anim"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="startStopAnim"
android:text="startOrStop"
android:textAllCaps="false"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.motion.widget.MotionLayout>
</layout>
viewModel:
class ErrorViewModel : ViewModel() {
private val _countDown: MutableLiveData<String> = MutableLiveData()
val mCountDown: LiveData<String> = _countDown
private val _anim: MutableLiveData<Boolean> = MutableLiveData()
val mAnim: LiveData<Boolean> = _anim
private var count = 0
private var state = false
init {
viewModelScope.launch(Dispatchers.IO) {
while (true) {
delay(1000)
_countDown.postValue(count++.toString())
}
}
}
fun anim() {
state = !state
_anim.value = state
}
}
#BindingAdapter("anim")
fun anim(layout: MotionLayout, play: Boolean?) {
play?.let {
if (it) {
layout.transitionToEnd()
} else {
layout.transitionToStart()
}
}
}
motionScene:
For simplicity, Scene has only one duration
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:app="http://schemas.android.com/apk/res-auto">
<Transition
app:constraintSetEnd="#+id/end"
app:constraintSetStart="#+id/start"
app:duration="2000" />
</MotionScene>
gif
As you can see in the gif, when there is no click, everything works fine for the numbers, but when I click the button, a 2 second animation starts, during which time my text doesn't display properly.
Of course, this is just a demo example. In a real scene, not only the text is not displayed completely, but even the TextView And ImageView are misplaced, and once the animation is executed, it cannot be recovered.
Can someone help me...
Actually in a real scene, the parent layout (B) of the problematic TextView (A) would perform a displacement animation. As long as this animation is executed once, the constraint relationship of TextView A will definitely have problems and cannot be restored (onResume can be restored after onPause is currently found)
By design during animation MotionLayout does not honor requestLayout.
Because in the majority of applications it is not needed and would have a significant impact on performance.
To enable it in the transition add
<Transition ... motion:layoutDuringTransition="honorRequest" \>
I have to implement click listener using binding and ViewModel as per clean architecture.
I have two button to select language like English and Chinese.
LanguageActivity.kt
#AndroidEntryPoint
class LanguageActivity : PBActivity(R.layout.activity_language) {
private val mViewModel:LanguageViewModel by viewModels()
private val mBinding:ActivityLanguageBinding by viewbind()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding.apply {
lifecycleOwner = this#LanguageActivity
viewModel = mViewModel
}
collectFlow(mViewModel.uiState){
Toast.makeText(this, it.name, Toast.LENGTH_SHORT).show()
when(it){
LanguageSelected.ENGLISH -> {
}
LanguageSelected.CHINESE -> {
}
LanguageSelected.NONE -> {
}
}
}
}
}
enum class LanguageSelected{
ENGLISH,CHINESE,NONE
}
LanguageViewModel.kt
#HiltViewModel
class LanguageViewModel #Inject constructor(
private val pbPrefs: PBPrefs
): ViewModel(){
// Backing property to avoid state updates from other classes
private val _uiState = MutableStateFlow(LanguageSelected.NONE)
// The UI collects from this StateFlow to get its state updates
val uiState: StateFlow<LanguageSelected> = _uiState
fun englishSelected()= viewModelScope.launch {
_uiState.value = LanguageSelected.ENGLISH
pbPrefs.setLanguageSelect()
}
fun urduSelected() = viewModelScope.launch {
_uiState.value = LanguageSelected.URDU
pbPrefs.setLanguageSelect()
}
}
activity_language.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewModel"
type="uk.co.planetbeyond.telenorbluecollar.ui.language.LanguageViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.language.LanguageActivity">
<androidx.constraintlayout.widget.Guideline
android:id="#+id/center_vertical_gl"
android:layout_width="match_parent"
android:layout_height="1dp"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
<Button
android:id="#+id/englishTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="English "
android:onClick="#{() -> viewModel.englishSelected()}"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toStartOf="#id/center_vertical_gl"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/urduTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Urdu"
android:onClick="#{() -> viewModel.urduSelected()}"
android:layout_marginStart="8dp"
app:layout_constraintStart_toEndOf="#id/center_vertical_gl"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
I have to select language on click of a button. What's the best approach as per clean architecture to implement
I have created an interface LanguageSelected but for that I have to created multiple methods in viewModel, As languages increase I have to create more methods in viewmodel.
How could I make it short or I mean extensible?
I have a MVVM setup for my project and I have a simple layout with an EditText and a button and when I click the button I want to show Text which is in the EditText.
For the button when i add. this code android:onClick="#={() -> addProductViewModel.addProduct()}" it gives me an error A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptExecution
and when I remove that like app builds okay.
Error is not so clear and I am not sure how to fix it.
here is my code
add_product.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android" >
<data class=".AddProductBinding">
<variable
name="addProductViewModel"
type="com.rao.iremind.AddProductViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="#+id/etProductName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:text="#={addProductViewModel.inputProductName}"
android:hint="Product name"
android:inputType="textPersonName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/btn_add_product"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="160dp"
android:text="Add product"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/etProductName" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
AddProductViewModel
class AddProductViewModel (
private val repository: ProductRepository,
private val context: Context
): ViewModel(), Observable {
#Bindable
val inputProductName = MutableLiveData<String>()
fun addProduct() {
//inputProductName.value
Toast.makeText(context, " add product ", Toast.LENGTH_LONG).show()
}
override fun removeOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback?) {
}
override fun addOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback?) {
}
}
AddProductViewModelFactory
class AddProductViewModelFactory (
private val repository: ProductRepository,
private val context: Context
) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(AddProductViewModel::class.java)) {
return AddProductViewModel(repository, context) as T
}
throw IllegalArgumentException("Unknown View Model class")
}
}
Your help and suggestions are much appreciated
Thanks
R
I'm using the latest Nav Component (2.2.0-alpha01) in my project, and am presented with an issue I can't seem to resolve.
I have a splash animation - nothing serious, a custom background stretching to the whole screen, and a logo in the very middle, using ConstraintLayout. During the initial sync, I animate a custom animated VectorDrawable (let's call it #drawable/logo_animated), which uses the common #drawable/logo as a source, and applies animations to its groups.
To time the animation right, I created the following helper function:
fun ImageView.setRepeatingAnimatedVector(
#DrawableRes animationRes: Int,
delayMs: Long = 0,
startDelayMs: Long = 0,
shouldRunOptional: () -> Boolean = { false },
optionalRunnable: () -> Unit = {}
) {
val anim = AnimatedVectorDrawableCompat.create(context, animationRes)?.apply {
registerAnimationCallback(object : Animatable2Compat.AnimationCallback() {
override fun onAnimationEnd(drawable: Drawable?) {
this#setRepeatingAnimatedVector.postDelayed({ if (shouldRunOptional()) optionalRunnable() else start() }, delayMs)
}
})
}
setImageDrawable(anim)
postDelayed({ anim?.start() }, startDelayMs)
}
It takes an AnimatedVectorDrawable as an input, and applies it to the ImageView. Upon finishing the animation cycle, a check in the form of a lambda (shouldRunOptional) is ran. If it returns true, the optionalRunnable lambda is launched, otherwise it repeats the animation.
With this, I can wait for the ViewModel to finish syncing, and then await the end of the animation to move between fragments without any weirdness. The animation itself is short (~900ms), so at most the user will be delayed by a second.
I also use a custom NavigationManager composition for navigation. The Manager itself is an interface (INavigationManager) of generic calls (such as splashToLanding() or openDetail(id: UUID)) that gets injected into ViewModels, with an extra interface taking care of the NavComponent specific bits:
IFragmentNavigator.kt
interface IFragmentNavigator {
val command: SingleLiveEvent<NavigationCommand>
var splashLandingExtras: Navigator.Extras?
fun setSplashLandingTransition(extras: Navigator.Extras) {
splashLandingExtras = extras
}
fun back() {
navigate(NavigationCommand.Back)
}
fun navigate(direction: NavDirections) {
navigate(NavigationCommand.To(direction))
}
fun navigate(navCommand: NavigationCommand) {
command.postValue(navCommand)
}
}
The implementation just takes care of property initializations, and then later on used in the following manner:
class FragmentNavigationManager:
INavigationManager, IFragmentNavigator by FragmentNavigator() { [...] }
The command property of this interface is then later used in the Fragments, via Observers:
open val navigationObserver = Observer<NavigationCommand> {
when(it) {
is NavigationCommand.To -> findNavController().navigate(it.directions)
is NavigationCommand.Back -> findNavController().popBackStack()
is NavigationCommand.BackTo -> findNavController().popBackStack(it.destinationId, false)
is NavigationCommand.ToRoot -> TODO()
}
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
navigator.command.observe(this, navigationObserver)
}
The Directions instance created in the FragmentNavigationManager is used by the NavController directly. I made sure to add the FragmentNavigator's Extras field to the actual navigation call:
override fun splashToLanding() {
navigate(
NavigationCommand.To(
SplashFragmentDirections.actionSplashFragmentToLandingFragment(),
null, null, splashLandingExtras
)
)
}
And of course in the SplashFragment, I assign the appropriate view to the transition name for splashLandingExtras:
navigator.splashLandingExtras = FragmentNavigatorExtras(binding.logo to "logo")
In the LandingFragment's onCreate method, I do set up enter and exit animations:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
TransitionInflater.from(context).inflateTransition(android.R.transition.move).let {transition ->
sharedElementEnterTransition = transition
sharedElementReturnTransition = transition
}
}
The layouts are the following:
splash.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewModel"
type="com.felcana.app.viewmodel.SplashViewModel" />
</data>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<include layout="#layout/background" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<ImageView
android:id="#+id/logo"
style="?attr/logoStyle"
android:transitionName="logo"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>
landing.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewModel"
type="com.my.app.viewmodel.LandingViewModel" />
</data>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<include layout="#layout/background" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<ImageView
android:id="#+id/logo"
style="?attr/logoStyle"
android:layout_marginBottom="24dp"
android:transitionName="logo"
app:layout_constraintBottom_toTopOf="#id/button_register"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<com.google.android.material.button.MaterialButton
android:id="#+id/button_register"
style="?attr/flatWhiteButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="8dp"
android:onClick="#{() -> viewModel.goToRegister()}"
android:text="#string/button_register"
app:layout_constraintBottom_toTopOf="#id/button_login"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<com.google.android.material.button.MaterialButton
android:id="#+id/button_login"
style="?attr/borderlessWhiteButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="24dp"
android:onClick="#{() -> viewModel.goToLogin()}"
android:text="#string/button_login"
app:layout_constraintBottom_toTopOf="#id/disclaimer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="#+id/disclaimer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="32dp"
android:maxLines="2"
android:textAlignment="center"
android:textColor="#color/app_white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:text="#tools:sample/lorem/random" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>
For some reason, the animation does not play at all - the ImageView just jumps without any sort of transition to the new position.
What's going wrong here? According to the documentation, this should be working. I did try going back to more stable versions of the NavComponent library, to no avail.
Have you tried postponing the enter transition inside LandingFragment::onViewCreated and manually setting the transition name to the view?
Something like this:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// Pause the enter transition
postponeEnterTransition()
// Manually apply the transitionName
logo.transitionName = "logo"
// Resume the transition
startPostponedEnterTransition()
super.onViewCreated(view, savedInstanceState)
}
I am using databinding in my application but button is not working. where am i making mistake in this code. i tried many solution but no luck. but if make button in activity_login.xml then button click works. i think i am not able to pass the view model to the included view.
Here is my code
activity_login.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:bind="http://schemas.android.com/apk/res-auto">
<data>
<variable
name ="loginViewModel"
type="com.innowi.checoutrestaurantdashboard.view.main.MainViewModel"/>
</data>
<android.support.constraint.ConstraintLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/login_constraint_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/login_background_burgerstack"
android:isScrollContainer="false"
android:paddingEnd="32dp"
android:paddingStart="32dp"
tools:context=".view.main.LoginActivity">
<include
android:id="#+id/login_layout"
layout="#layout/layout_login"
android:layout_width="0dp"
android:layout_height="0dp"
bind:loginViewModel="#{loginViewModel}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>
</layout>
layout_login.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name ="loginViewModel"
type="com.innowi.checoutrestaurantdashboard.view.main.MainViewModel"/>
</data>
<android.support.constraint.ConstraintLayout
style="#style/Login"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:isScrollContainer="false"
android:padding="32dp">
<Button
android:id="#+id/login_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:background="#drawable/button_login_drawable"
android:enabled="false"
android:gravity="center"
android:paddingBottom="16dp"
android:paddingTop="16dp"
android:text="#string/button_sign_in"
android:textColor="#color/colorWhite"
android:textSize="24sp"
android:onClick="#{loginViewModel::onLoginButtonClick}"
app:layout_constraintLeft_toLeftOf="#+id/login_username"
app:layout_constraintRight_toRightOf="#+id/login_username"
app:layout_constraintTop_toBottomOf="#+id/login_password" />
.
.
.
.
</android.support.constraint.ConstraintLayout>
</layout>
MainViewModel.kt
class MainViewModel #Inject constructor(
private val loginRepository: LoginRepository
) : BaseViewModel() {
fun onLoginButtonClick(view : View){
performLogin()
}
.
.
.
}
LoginActivity.kt
class LoginActivity : AppBaseActivity() {
private lateinit var loginViewBinding: ActivityLoginBinding
private lateinit var viewModel: MainViewModel
private val TAG = LoginActivity::class.simpleName
override fun initViewModel(viewModelProvider: ViewModelProvider): BaseViewModel? {
viewModel = viewModelProvider.get(MainViewModel::class.java)
return viewModel
}
override fun render(state: ViewState) {
when (state) {
is LoadingState -> {
// loading
val loading = state.loading
Log.d(TAG,"Loading State")
}
is DefaultState -> {
// render Data
val data = state.data
Log.d(TAG,"Data State")
}
is ErrorState -> {
// show error
val error = state.error
Log.d(TAG,"Loading State")
}
}
}
override fun setContentView() {
loginViewBinding = DataBindingUtil.setContentView(this, R.layout.activity_login)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
loginViewBinding.loginViewModel = viewModel
loginViewBinding.executePendingBindings()
}
}