reactiveui / rfcs

RFCs for changes to ReactiveUI
https://reactiveui.net/rfcs
5 stars 5 forks source link

RFC: [Core Team] Improving list-based databinding, documentation and standardising (mobile) platforms #9

Open Qonstrukt opened 6 years ago

Qonstrukt commented 6 years ago

Improving list-based databinding, documentation and standardising (mobile) platforms

Summary

I think list-based navigation and data insight is one of the most commonly seen UI/UX paradigms on current mobile platforms, even desktop platforms before that. But for this RFC I'm focussing on iOS and Android since that is what I know best.

I've noticed that data-binding list- or collection-based data to multiple platforms is currently cumbersome because of platform differences, and how ReactiveUI is currently heavily mirroring platform-available functionality only.

Motivation

The data itself is often identical across platforms, so it would be great if it could be treated as such. Unfortunately both iOS and Android both have different platform-level features for handling data in list- or collection-based formats. iOS for example offers sections, where Android does not (by default). ReactiveUI in itself has adapted to the platforms by offering, for example, TableSectionInformation on iOS to supply a TableViewSource with section information. This means you'll need to reformat your data on iOS the group sections based on one or multiple properties, and while this isn't necessarily hard, it's cumbersome and requires quite some boilerplate every time. It can also complicate things like searching or filtering since the data formatted in your ViewModel may not end up being what's presented in the view.

I'm personally not a big fan of abstracting platform-level features to some most-common denominator of all. Hence why I refuse to use Forms for anything else than a simple prototype. But in the end you're often recreating the same section experience on Android and it would be nice if ReactiveUI could help you with this so you can format your data from the source.

Detailed design

This is the current state of affairs on Android: You can create an instance of ReactiveRecylerViewAdapter for every collection change, and supply the new IReadOnlyReactiveList to the adapter.

On iOS you have a lot more options: You can use BindTo to bind your IReadOnlyReactiveList directly to a TableView or CollectionView. Or you can do the equivalent to what you can on Android and create your own ReactiveTableViewSource or ReactiveCollectionViewSource. You then have the option to supply an IReadOnlyList of TableSectionInformation which allows you to specify section grouping, headers and footers.

I would propose to bring TableSectionInformation (or CollectionViewSectionInformation) to the NETStandard library, remove features that are platform or view specific like InitializeCellAction, maybe replace them with platform-independent variants purely to prepare data for cell representation.

In the case you do want to initialise the cell layout or view holder properties, it's still easy to extend these in the platform projects if you so desire using your own Adapter or DataSource implementations. This way it's easier for most use-cases to get started with section-based list data, but it's still extendable for advanced usage.

Lastly there needs to come a ReactiveRecyclerViewAdapter implementation with support for sections. It might be insightful to look into how other projects have implemented this. I haven't done extensive research on this front yet. Any ideas are welcome!

Bonus; Maybe we could also bring the BindTo syntax of iOS to Android or other platforms where this is useful.

How we teach this

Currently there's almost no documentation regarding data binding of lists on any platform as far as I can find. I had to discover methods like BindTo on UITableView myself, and had to look into the source of ReactiveUI to find out how it even works.

I've been thinking of writing docs long before today, but it's a confusing mess at the moment due to the differences in platform implementations. So I feel a refactoring is warranted before even getting started on docs.

Drawbacks

Well, for starters, I hardly have any experience with or interest in any other platforms than iOS or Android

We would also impose some more platform-dependency and effort to keep the SectionInformation implementation working with all supported platforms, but I feel this is worth the trouble as it would seriously improve the developer experience.

Other than that I think we could deprecate the current implementations on iOS (because I don't think Android would be affected a lot) but keep it intact until vNext without too many consequences to ease transitioning.

Alternatives

The alternative would be to not do a lot about it, maybe only introduce some BindTo functionality to other platforms and finally write up some docs on how to use it.

Unresolved questions

  • How are people currently handling the differences in implementation of these types of data per platform?
  • Can we adopt this idea to Forms as well? (Looking at the docs it seems to support grouping.)
  • How can we best make current platform-features available like supplying a header cell identifier on iOS?
  • Are there any favourable implementations of sections based RecyclerViews on Android?
cabauman commented 6 years ago

I like this idea. I, too, mostly work with the native iOS and Android platforms, so I’d be interested in helping out where needed.

This is my favorite library for AndroidStudio RecyclerView: https://github.com/luizgrp/SectionedRecyclerViewAdapter

So I made binding for it here and started implementing the samples: https://github.com/cabauman/SectionedRecyclerViewBindings

GitHub
luizgrp/SectionedRecyclerViewAdapter
SectionedRecyclerViewAdapter - An Adapter that allows a RecyclerView to be split into Sections with headers and/or footers. Each Section can have its state controlled individually.
GitHub
cabauman/SectionedRecyclerViewBindings
SectionedRecyclerViewBindings - Xamarin Android bindings for SectionedRecyclerViewAdapter by luizgrp
Qonstrukt commented 6 years ago

Thanks for pointing to SectionedRecyclerViewAdapter. This raises a new question; whether or not this might be more useful as sort of plugin to ReactiveUI itself.

If we could make a very basic section implementation in ReactiveRecyclerViewAdapter I feel this wouldn’t be needed. But looking at this, things could quickly become quite extensive and we would have to specify clear borders on what exactly would be supported.

At the moment the table binding code for iOS is already quite extensive but stable and concise. It would be great if we could at least attain this level of support for Android as well.