Reputation: 158
I have to make a GET request every second and I have to update the UI with the incoming fresh data.
I managed to get the repeating network request working using a Timer
. I can see okhttp
logs showing the repeating responses with fresh data each second.
However, the UI is not updating with the new data. It only shows the data from the first request. I have tried to implement MVVM calling the network and returning a LiveData
to be observed in the fragment.
Edit: I just noticed the new data is being appended to the list as the recyclerview
now is growing and growing every second with new items.
ViewModel
class RatesViewModel : ViewModel() {
private val _rates = MutableLiveData<RatesResponse>()
val rates : LiveData<RatesResponse>
get() = _rates
fun init(base: String) {
timer("NetworkRequest",false, 0, 1000) {
viewModelScope.launch {
_rates.postValue(RatesRepository().getRates(base))
}
}
}
}
Fragment
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProvider(this).get(RatesViewModel::class.java)
viewModel.init("EUR")
val ratesLiveData = viewModel.rates
ratesLiveData.observe(viewLifecycleOwner, Observer { response ->
addElements(response.rates)
if (ratesAdapter == null) {
setUpRecyclerView()
} else {
ratesAdapter!!.notifyDataSetChanged()
}
})
setUpRecyclerView()
}
Add element function
private fun addElements(allRates: Rates) {
ratesList.add(Currency(
"EUR", "Euro", R.drawable.eur, 1.00))
ratesList.add(Currency(
"AUD", "Australian Dollar", R.drawable.aud, allRates.AUD))
ratesList.add(Currency(
"BGN", "Bulgarian Lev", R.drawable.bgn, allRates.BGN))
ratesList.add(Currency(
"BRL", "Brazilian Real", R.drawable.brl, allRates.BRL))
ratesList.add(Currency(
"CAD", "Canadian Dollar", R.drawable.cad, allRates.CAD))
ratesList.add(Currency(
"CHF", "Swiss franc", R.drawable.chf, allRates.CHF))
ratesList.add(Currency(
"CNY", "Chinese Yuan", R.drawable.cny, allRates.CNY))
ratesList.add(Currency(
"CZK", "Czech Koruna", R.drawable.czk, allRates.CZK))
ratesList.add(Currency(
"DKK", "Danish Krone", R.drawable.dkk, allRates.DKK))
ratesList.add(Currency(
"GBP", "British Pound", R.drawable.gbp, allRates.GBP))
ratesList.add(Currency(
"HKD", "Hong Kong Dollar", R.drawable.hkd, allRates.HKD))
ratesList.add(Currency(
"HRK", "Croatian Kuna", R.drawable.hrk, allRates.HRK))
ratesList.add(Currency(
"HUF", "Hungarian Forint", R.drawable.huf, allRates.HUF))
ratesList.add(Currency(
"IDR", "Indonesian Rupiah", R.drawable.idr, allRates.IDR))
ratesList.add(Currency(
"ILS", "Israeli Shekel", R.drawable.ils, allRates.ILS))
ratesList.add(Currency(
"INR", "Indian Rupee", R.drawable.eur, allRates.INR))
ratesList.add(Currency(
"ISK", "Icelandic Króna", R.drawable.isk, allRates.ISK))
ratesList.add(Currency(
"JPY", "Japanese Yen", R.drawable.jpy, allRates.JPY))
ratesList.add(Currency(
"KRW", "South Korean Won", R.drawable.krw, allRates.KRW))
ratesList.add(Currency(
"MXN", "Mexican Peso", R.drawable.mxn, allRates.MXN))
ratesList.add(Currency(
"MYR", "Malaysian Ringgit", R.drawable.myr, allRates.MYR))
ratesList.add(Currency(
"NOK", "Norwegian Krone", R.drawable.nok, allRates.NOK))
ratesList.add(Currency(
"NZD", "Bulgarian Lev", R.drawable.bgn, allRates.BGN))
ratesList.add(Currency(
"PHP", "Philippine Peso", R.drawable.php, allRates.PHP))
ratesList.add(Currency(
"PLN", "Polish Złoty", R.drawable.pln, allRates.PLN))
ratesList.add(Currency(
"RON", "Romanian Leu", R.drawable.ron, allRates.RON))
ratesList.add(Currency(
"RUB", "Russian Rouble", R.drawable.rub, allRates.RUB))
ratesList.add(Currency(
"SEK", "Swedish krona", R.drawable.sek, allRates.SEK))
ratesList.add(Currency(
"SGD", "Singapore Dollar", R.drawable.sgd, allRates.SGD))
ratesList.add(Currency(
"THB", "Thai Baht", R.drawable.thb, allRates.THB))
ratesList.add(Currency(
"USD", "United States Dollar", R.drawable.usd, allRates.USD))
ratesList.add(Currency(
"ZAR", "South African Rand", R.drawable.zar, allRates.ZAR))
}
Upvotes: 0
Views: 471
Reputation: 158
I fixed it by calling the clear()
method on the list at start of the addElemenet()
function.
I don't think this is the right thing to do, though.
Upvotes: 0
Reputation: 1234
Did some formatting to separate different parts of logic
class RatesViewModel : ViewModel() {
private val _rates = MutableLiveData<RatesResponse>()
val rates : LiveData<RatesResponse>
get() = _rates
fun setupTimer(zone: String) = viewModelScope.launch {
timer("NetworkRequest",false, 0, 1000) {
val latestRates = getRates(zone)
_rates.postValue(latestRates)
}
}
suspend fun getRates(zone: String) = RatesRepository().getRates(zone)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProvider(this).get(RatesViewModel::class.java)
viewModel.setupTimer("EUR")
val ratesLiveData = viewModel.rates
ratesLiveData.observe(viewLifecycleOwner, Observer { response ->
addElements(response.rates)
})
/**
* Your recyclerView should not get setup again and again anytime a new value is posted in the livedata.
*/
if (ratesAdapter == null) setUpRecyclerView()
else ratesAdapter!!.notifyDataSetChanged()
}
You mentioned that the new data is getting appended at the end of the list i.e. allRates
, in that case instead of ADD
use UPDATE
, as ADD will not remove the old elements.
Upvotes: 1