Как проверить сначала или нет на GroupedObservable, используя Rx Android? - PullRequest
0 голосов
/ 22 февраля 2020

Я использую RecyclerView , чтобы показать заголовок и тело с одним отличием, что я использую библиотеку Rx для достижения этой цели. По сути, я отправляю оповещения с помощью FCM в свое приложение, и оно отображается в виде переработчика. Это работало нормально и даже обновлялось в режиме реального времени благодаря Rx. Тем не менее, я представляю группирование по дате функцию для этого и изменил код для реализации этого. Вот как это выглядит сейчас:

@Inject
lateinit var rxSharedPreferences: RxSharedPreferences

@Inject
lateinit var gson: Gson

val days: MutableList<String> = mutableListOf()

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    return inflater.inflate(R.layout.fragment_alerts, container, false)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    val alertsPref = rxSharedPreferences.getObject("alerts", emptyList(), AlertsPreferenceAdapter(gson))
    val alerts = alertsPref.get().sortedBy { it.created_at.timeInMillis }

    val rxDataSource = RxDataSource<AlertItemBinding, Alert>(R.layout.alert_item, alerts)
    disposables.add(
        rxDataSource.asObservable()
            .groupBy { SimpleDateFormat.getDateInstance().format(it.item?.created_at?.time!!) }
            .subscribe { // 'it' is now a GroupedObservable<String, SimpleViewHolder<Alert, AlertItemBinding>!>!
                val key = it.key
                it.subscribe { value ->
                    val item = value.item!!
                    val binding = value.viewDataBinding!!

                    if(days.contains(key)) {
                        binding.tvHeading.visibility = View.GONE
                        binding.tvMessage.text = item.message
                    } else {
                        days.add(key!!)

                        when {
                            DateUtils.isToday(item.created_at.timeInMillis) -> binding.tvHeading.text = getString(R.string.today)
                            else -> binding.tvHeading.text = key
                        }
                        binding.tvMessage.text = item.message
                    }
                }
            }
    )

    disposables.add(alertsPref.asObservable()
        .subscribe { alertsList ->
            val sortedAlerts = alertsList.sortedByDescending { it.created_at.timeInMillis }
            rxDataSource.updateDataSet(sortedAlerts).updateAdapter()
        }
    )

    rvAlerts.layoutManager = LinearLayoutManager(context)
    rxDataSource.bindRecyclerView(rvAlerts)
}

Это полный код этого фрагмента предупреждения. Вот что я делаю:

  1. Он принимает сохраненные оповещения и загружает их изначально. Я использую эту библиотеку для сохранения / загрузки настроек.
  2. Затем она также подписывается на настройки в случае поступления новых предупреждений.
  3. Поскольку RecyclerView также является Rx Когда данные изменяются, они обновляют представление переработчика новыми элементами.

Переменная val days: MutableList<String> = mutableListOf() - это хак, который я написал, чтобы добиться того, что я делаю, за исключением того, что он не элегантен. Я добавляю в список ключ date , а затем позволяю заголовку появляться в первый раз, тогда как, если день уже существует в списке, он скрывает заголовок - так что это Цель состоит в том, чтобы показать секционные оповещения, но не элегантно, потому что, когда новые оповещения появляются на экране и наблюдаемые обновляются, чтобы включить новые значения, он группирует все старые дни в один раздел без заголовка даты (я предполагаю, что существует некоторая проблема с параметром days, который должен быть очищен или что-то в этом роде.

Я хочу сгруппировать по дням в самой GroupedObservable. Примерно так было бы идеально:

.subscribe {
    val key = it.key
    if(it.subscribeIfFirst) {
       // Do logic to show header as well as date
    }
    else if (it.subscribeNonFirst) {
      // Do logic to hide header go date appears below
    }
}

Но я понятия не имею, как этого добиться в Rx. Вот скриншоты того, как это должно выглядеть. Надеемся на хорошее решение - заранее спасибо:

screenshot of output

...