0

TLDR version:

We have an array of ItemAs and a second array of ItemBs. We want to display them in a single scrollable 'list' on the screen, but hopefully keeping their management, etc. separate.

Full Question:

Consider you have two lists of data you want to show together in one scrollable area on the screen. You can't simply place two ListViews in a vertical LinearLayout because the lists scroll individually, not as one union list. What we want is one scrollable region that contains both lists (i.e. the LinearLayout is what's actually scrolled, but the two lists inside it are fully expanded.)

e.g.

ItemTypeA
ItemTypeA
ItemTypeA
ItemTypeA
ItemTypeB  <-- Note the second 'data' list starts here but is in the same UI list.
ItemTypeB
ItemTypeB
ItemTypeB
ItemTypeB
ItemTypeB

I also don't mind if the 'rows' aren't recycled (i.e. they still exist when scrolled off the screen) since there aren't that many of them (maybe 25 or so: ~10 of the first type, then ~15 of the second type.)

Now in a perfect world, I could simply tell the ListViews to not scroll, hoping they would 'expand out' but didn't get anywhere there.

I also just tried a straight-up vertical LinearLayout where I manually inserted the rows, but that made maintenance a nightmare.

The final thing I tried is just using one ListView, but combining the data from the two lists into a single array and going from there. It works but it just feels sooo 'tacky' and also intermingles two distinct UI portions which reads of code-smell to me.

In iOS, I'd simply create a UITableView with two sections and each section would manage its own set of rows; the first section would manage the first list of data and the second the other. The UITableView would then just scroll them all together in one on-screen list which would work perfectly. But I don't know of anything similar in Android (although I'm admittedly new at it.)

So what is the proper 'Android' way(s) to do this?

Mark A. Donohoe
  • 28,442
  • 25
  • 137
  • 286
  • Why are you splitting the content into 2 lists? – Tim Jul 19 '17 at 14:59
  • Two completely different data sets from two different sources, technically managed by two different developers. We just want them displayed together on one scrollable screen. – Mark A. Donohoe Jul 19 '17 at 15:00
  • You might try this solution https://stackoverflow.com/questions/1778485/android-listview-display-all-available-items-without-scroll-with-static-header/1958482 (2nd answer) to expand a listview, and put both the listviews in a scrollview – Tim Jul 19 '17 at 15:03
  • To clarify- you want 2 lists on top of each other that scroll at the same rate? I don't think I've actually seen an Android app do that. There is definitely no built in utility I can think of that would do it. The best solution would probably be a single RecyclerView with a custom LayoutManager. The quickest hack would be to hook the onScroll of both lists and force the other list to scroll to match. – Gabe Sechan Jul 19 '17 at 15:03
  • No, not two lists scrolling in sync. From a data perspective they are two different lists, but from the UI perspective, it's just one. Make sense? As I said above, we can just combine the list data into one array and do it that way, but that intermingles design/functionality which we're trying to avoid. If we had an items control which simply repeated data without doing scrolling or the like, that would be perfect for use in the LinearLayout. – Mark A. Donohoe Jul 19 '17 at 15:04
  • *So what is the proper 'Android' way(s) to do this?* to answer that, I have never seen this behavior before. It might not be the best design – Tim Jul 19 '17 at 15:05
  • Ok, so one list with all the data from one on top of all the data from the other? A single List/RecyclerView can do that. Adapters do not need to return data from a single source, or of a single view type. – Gabe Sechan Jul 19 '17 at 15:06
  • Lists are *everywhere* in Android! This is just a UI list but it's made from the union of two distinct data sets. – Mark A. Donohoe Jul 19 '17 at 15:07
  • 1
    Another way would be a single list with a compound adapter made of 2 subadapters, that outputs all the items in adapter 1 then all the items in adapter 2. That may be architecturally cleaner. – Gabe Sechan Jul 19 '17 at 15:07
  • The compound adapter part sounds interesting, and definitely something I'm going to look into more. It's just a shame that it requires a code change when technically this is purely a UI thing. Stack of ItemAs on top of a Stack of ItemBs all scrolling together. – Mark A. Donohoe Jul 19 '17 at 15:09
  • It isn't just a UI change when you add in recycling. If you didn't want recycling, you could do it by throwing all the individual views in a LinearLayout inside of a ScrollView. – Gabe Sechan Jul 19 '17 at 15:11
  • I've addressed exactly that in my question. We don't need recycling, but we also do want the layouts to reflect the data, which hard-coding can't do. – Mark A. Donohoe Jul 19 '17 at 15:12
  • You could easily have done it by creating the layout in java instead of xml. Read in data. Loop over it. Create appropriate view type. Add to linear layout. It seems like you're trying to think of it in an all xml way, when that isn't appropriate to this type of problem – Gabe Sechan Jul 19 '17 at 15:14
  • That's a bad design pattern because as I said, that mixes intents, and effectively, you've just taken the work of an Adapter and moved it to your own code where you have now also lost all the benefits of ListView. What's needed is a non-recycling, non-scrolling list which you can simply insert into a LinearLayout. Perhaps that's the real way to go. Roll one of those. That way Layouts, not code, dictate the order, which is what we're after. – Mark A. Donohoe Jul 19 '17 at 15:32
  • Actually, going further, perhaps a subclass of LinearLayout that takes an adapter is all that's needed. Then you can nest two of those in the parent LinearLayout which itself is wrapped in a ScrollView. That still allows a pure-XML way to achieve this (once you have that subclass available to be used for each 'section' of the list.) – Mark A. Donohoe Jul 19 '17 at 15:37
  • @Gabe, if you put the compound adapter approach in an answer, I'll give it to you. – Mark A. Donohoe Jul 20 '17 at 14:36

0 Answers0