0

Based on the idea that you should not pass and Android view's or other pure Android components to ViewModel, or have android imports there, consider the next use case:

From my Fragment I want to launch some sort of image processing action and for that I need to initialize my object with the current xml view where I want to show the result. So I create it on the ``Fragment side with the view component and then pass that object over to ViewModel.

My problems are:

  1. I'm passing to ViewModel an object with already reference to an Android views.

  2. The logic in ViewModel creates a Bitmap and after processing it return that bitmap to the Fragment that observes it, as a result I have reference to some Android Bitmap libraries inside my ViewModel

How to avoid referencing Android stuff in ViewModel if I need the work to be done there?

RonTr
  • 137
  • 10
  • Hi, can you formulate a clear question statement? – Stefan May 01 '18 at 12:04
  • @Stefan Updated – RonTr May 01 '18 at 12:06
  • Well, if you need the work to be done there, it would be difficult not to reference *the android stuff*. I think the main question is: do you want to do the work in your ViewModel or do you want to use your ViewModel to trigger the action? – Stefan May 01 '18 at 12:09
  • Part of that processing involves some third party libraries, that's why I didn't want to throw it on the View part – RonTr May 01 '18 at 12:13
  • What I normally do, although I am definitely not an android expert, is to create an abstract interface for the processing you have in mind, wrap the logic in a concrete class which contains the actual conversion, and pass that object, as interface to the ViewModel. That way you have limited all the dependencies to that single concrete. – Stefan May 01 '18 at 12:20

1 Answers1

0

If I understood you correctly, you are inflating your views in the Fragment, then you generate the bitmap in your ViewModel, and then you pass it back and set it in your Fragment, and in the process you need to pass something more to the ViewModel than just Application instance. If that's the case you need to use the ViewModelFactory. In short, you will write a small class that will create the ViewModel for you, and then you pass it to ViewModelProviders.of(this, ...) as a second parameter.

The usage is shown in this answer. If you look around you should also be able to find its usage in Google samples.

Suleyman
  • 2,765
  • 2
  • 18
  • 31
  • Yes, you're right with first the part, as for the factory idea, I'm not sure I need it because I can just call the method and pass whatever I want to. My real problem is that I end up with a ViewModel that has references to Android stuff like `import android bitmap` which is not recommended to do. I don't need the use of `Application` – RonTr May 02 '18 at 04:33
  • @RonTr Yep, so it doesn't introduce leaks. Well, in that case, my answer doesn't make much sense :) you need some sort of a repository layer between the ViewModel and the View. Maybe if your Bitmap is generated from an API or a database you can introduce a repository layer between the ViewModel and the Database or the source that you get the image from, that may help the abstraction. But other than that I don't know. Make sure to post the solution if you find it :) – Suleyman May 02 '18 at 07:28