0

Currently I have two fragments, one that shows the weather for a place and another that let's you select a point in a map and redirects you to the other fragment showing the weather for that point.

What I want to achieve is to have by default the user's location and give the option to the user by going to the map of selecting any other place. So I would like to:

  • Get lat/lng via GPS and then "upload" it to somewhere that would share those values between this fragment and the map fragment (The activity maybe?)
  • If a point in the map is selected update those values- Both fragments can read at any time, only map fragment can update

I believe I can do this sketchily adding getters/setters to my activity and then in the fragments cast the activity to my particular activity. But this just seems bad. What would be the correct way to do it? What I have now:

  • MainActivity (connects both fragments through a bottom navigation bar)
  • ForecastFragment (Shows the weather for lat/lng)
  • ForecastViewModel
  • MapFragment
  • MapViewModel
  • WeatherRepository
  • WeatherAPI (through RetroFit updates values)

I'm using dagger and kotlin.

Thanks!

Levon
  • 250
  • 2
  • 12
  • https://stackoverflow.com/questions/44272914/sharing-data-between-fragments-using-new-architecture-component-viewmodel – ADM Apr 27 '20 at 04:13

1 Answers1

1

Share a common view model between ForecastFragment and MapFragment using the activity scope

Take a look at the example provided here Share data between fragments

class SharedViewModel : ViewModel() {
    val selected = MutableLiveData<Item>()

    fun select(item: Item) {
        selected.value = item
    }
}

class MasterFragment : Fragment() {

    private lateinit var itemSelector: Selector

    // Use the 'by activityViewModels()' Kotlin property delegate
    // from the fragment-ktx artifact
    private val model: SharedViewModel by activityViewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        itemSelector.setOnClickListener { item ->
            // Update the UI
        }
    }
}

class DetailFragment : Fragment() {

    // Use the 'by activityViewModels()' Kotlin property delegate
    // from the fragment-ktx artifact
    private val model: SharedViewModel by activityViewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        model.selected.observe(viewLifecycleOwner, Observer<Item> { item ->
            // Update the UI
        })
    }
}

Note:

Both fragments must handle the scenario where the other fragment is not yet created or visible.

shb
  • 5,957
  • 2
  • 15
  • 32
  • Thanks for answering! One question, are you suggesting having only one viewmodel or three(weather,forecast,shared)? – Levon Apr 27 '20 at 11:43
  • Both are fine, depends on your use case. whatever makes sense to you. – shb Apr 27 '20 at 14:24