BitNeBolt
@BitNeBolt

На каком этапе лучше преобразовывать данные?

К примеру, есть сущность человека: возраст, пол, рост.

Для отображения списка сущностей используется RecyclerView.

На экране должны отображаться изменённые данные: рост перевестись в другие единицы измерения, а пол и возраст должны быть отформатированы по шаблону.

На каком этапе лучше преобразовывать данные, чтобы не замедлять ui поток?
Если описывать сущность элемента списка, то какой тип данных должен быть у полей: строки (чтобы в текстовые поля сразу устанавливать нужнве значения) или же соответствующие логике (например, возраст - int, чтобы было удобнее работать с ней в других частях программы)?
А если данные поступают с сервера, но должны отображаться с настройками пользователя (он вводит их только один раз, но может изменить), то кто должен преобразовывать: сервер или устройство пользователя, если второе, то на каком этапе и как лучше описать сущность?
  • Вопрос задан
  • 83 просмотра
Решения вопроса 1
zagayevskiy
@zagayevskiy Куратор тега Android
Android developer at Yandex
У нас обычно есть моделька для логики, что-то типа
data class Human(val age: Int, val sex: Boolean, val height: Float): AutoParcelable
, где-то есть State, в котором хранится список таких моделек:
data class State(val humans: List<Human>): AutoParcelable

Есть стрим состояний Observable<State>. Для того, чтобы отобразить стейт на экране, есть ViewState:
data class HumanViewState(val formattedAge: String, val sex: Boolean, val formattedHeight: String)
data class ViewState(humans: List<HumanViewState>, diff: DiffUtil.DiffResult?)
есть маппер, который в бекграунде маппит стейты во вьюстейты, что-то типа:
class ViewStateMapper @Inject constructor(stateProvider: StateProvider<State>>) {
  fun viewStates(): Observable<ViewState> = stateProvider.states // эмиттит на бекграунд треде
        .distinctUntilChanged()
        .map { 
              // State -> ViewState
        }.scan {
           // вычислить дифф между текущим и предыдущим вьюстейтами
        }
}


и, в конце концов, есть вьюха, которая подписывается на маппер и рендерит стейты:
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()
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы