B
B
BitNeBolt2020-12-18 19:27:55
Android
BitNeBolt, 2020-12-18 19:27:55

At what stage it is better to transform the data?

For example, there is the essence of a person: age, gender, height.

RecyclerView is used to display a list of entities.

Changed data should be displayed on the screen: height should be converted to other units of measurement, and gender and age should be formatted according to the template.

At what stage is it better to convert the data so as not to slow down the ui stream?
If we describe the essence of a list element, then what type of data should the fields have: strings (in order to immediately set the necessary values ​​\u200b\u200bin text fields) or corresponding to logic (for example, age is int, so that it is more convenient to work with it in other parts of the program)?
And if the data comes from the server, but should be displayed with the user's settings (he enters them only once, but can change), then who should convert: the server or the user's device, if the latter, then at what stage and how best to describe the entity?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Denis Zagaevsky, 2020-12-19
@BitNeBolt

We usually have a model for logic, something like

data class Human(val age: Int, val sex: Boolean, val height: Float): AutoParcelable
, somewhere there is a State that stores a list of such models:
data class State(val humans: List<Human>): AutoParcelable

There is a state stream Observable<State>. In order to display the state on the screen, there is a ViewState:
data class HumanViewState(val formattedAge: String, val sex: Boolean, val formattedHeight: String)
data class ViewState(humans: List<HumanViewState>, diff: DiffUtil.DiffResult?)
there is a mapper that maps states to viewstates in the background, something like:
class ViewStateMapper @Inject constructor(stateProvider: StateProvider<State>>) {
  fun viewStates(): Observable<ViewState> = stateProvider.states // эмиттит на бекграунд треде
        .distinctUntilChanged()
        .map { 
              // State -> ViewState
        }.scan {
           // вычислить дифф между текущим и предыдущим вьюстейтами
        }
}

and finally there is a view that subscribes to the mapper and renders the states:
fragment/controller/etc

fun onViewCreated(....) {
  ....
   mapper.viewStates
       .observeOn(mainThreadScheduler)
       .subscribe(::render)
       .disposeWithView() 
}

private fun render(viewState: ViewState) {
     recyclerAdapter.items = viewState.humans
     viewState.diff?.dispatchUpdatesTo(recyclerAdapter) ?: recyclerAdapter.notifyDatasetChanged()
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question