Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use android navigation without binding to UI in ViewModel (MVVM)?

I am using android navigation that was presented at Google I/O 2018 and it seems like I can use it by binding to some view or by using NavHost to get it from Fragment. But what I need is to navigate to another specific view from ViewModel from my first fragment depending on several conditions. For ViewModel, I extend AndroidViewModel, but I cannot understand how to do next. I cannot cast getApplication to Fragment/Activity and I can't use NavHostFragment. Also I cannot just bind navigation to onClickListener because the startFragment contains only one ImageView. How can I navigate from ViewModel?

class CaptionViewModel(app: Application) : AndroidViewModel(app) {
private val dealerProfile = DealerProfile(getApplication())
val TAG = "REGDEB"


 fun start(){
    if(dealerProfile.getOperatorId().isEmpty()){
        if(dealerProfile.isFirstTimeLaunch()){
            Log.d(TAG, "First Time Launch")
            showTour()
        }else{
            showCodeFragment()
            Log.d(TAG, "Show Code Fragment")

        }
    }
}

private fun showCodeFragment(){
    //??
}

private fun showTour(){
    //??
}

}

My Fragment

class CaptionFragment : Fragment() {
private lateinit var viewModel: CaptionViewModel
private val navController by lazy { NavHostFragment.findNavController(this) }

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
    viewModel = ViewModelProviders.of(this).get(CaptionViewModel::class.java)
    return inflater.inflate(R.layout.fragment_caption, container, false)
}


override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)

    viewModel.start()

}

}

I want to keep logic of navigation in ViewModel

like image 573
Ekaterina Levchenko Avatar asked Jun 07 '18 12:06

Ekaterina Levchenko


People also ask

What is SavedStateHandle in ViewModel?

When using this module, ViewModel objects receive a SavedStateHandle object through its constructor. This object is a key-value map that lets you write and retrieve objects to and from the saved state. These values persist after the process is killed by the system and remain available through the same object.

How do you enable your project to use navigation components?

In the Project window, right-click on the res directory and select New > Android Resource File. The New Resource File dialog appears. Type a name in the File name field, such as "nav_graph". Select Navigation from the Resource type drop-down list, and then click OK.

What is the difference between ViewModel and Android ViewModel?

Android architecture components are the components that are used to build robust, clean, and scalable apps. Android architecture components hold some classes to manage UI components and Data persistence. The ViewModel class is designed to store and manage UI-related data in a lifecycle-conscious way.


1 Answers

How can I navigate from ViewModel?

The answer is please don't. ViewModel is designed to store and manage UI-related data.

New Answer

In my previous answers, I said that we shouldn't navigate from ViewModel, and the reason is because to navigate, ViewModel must have references to Activities/Fragments, which I believe (maybe not the best, but still I believe it) is never a good idea.

But, in recommended app architecture from Google, it mentions that we should drive UI from model. And after I think, what do they mean with this?

So I check a sample from "android-architecture", and I found some interesting way how Google did it.

Please check here: todo-mvvm-databinding

As it turns out, they indeed drive UI from model. But how?

  1. They created an interface TasksNavigator that basically just a navigation interface.
  2. Then in the TasksViewModel, they have this reference to TaskNavigator so they can drive UI without having reference to Activities / Fragments directly.
  3. Finally, TasksActivity implemented TasksNavigator to provide detail on each navigation action, and then set navigator to TasksViewModel.
like image 162
Yosi Pramajaya Avatar answered Sep 28 '22 09:09

Yosi Pramajaya