Mar 3 | 7:25 PM |
Mark M. | has entered the room |
Mark M. | turned on guest access |
Mar 3 | 7:45 PM |
Tad F. | has entered the room |
Mar 3 | 7:50 PM |
Tad F. |
Hi Mark!
|
Mark M. |
hello, Tad!
|
Mark M. |
how are you today?
|
Tad F. |
Plugging along....
|
Tad F. |
Trying not to think about Coronavirus or the election drama :)
|
Tad F. |
So here is a scenario I'm wrestling with...
|
Tad F. |
I have an abstract class that I use in several places that has a lot of the plumbing in it to provide a visual "Master-Detail" capability.
|
Tad F. |
The base layout this utilizes has an import statement for a commonly named layout, which varies based on whether the device is 600dp width or not.
|
Tad F. |
Basically if it is 600dp or greater, then this layout shows both the "master" list on the left side, and a "detail pane" for the selected item in that list on the right side.
|
Tad F. |
All good, and fairly standard I think.
|
Tad F. |
The issue now, is that I'm implementing a new class that extends the base class.
|
Tad F. |
I want everything that is in the base layout, but instead of this line that is in the base layout:
|
Tad F. |
<include layout="@layout/item_list" />
|
Tad F. |
I need to include a different layout *just for this one class*
|
Mar 3 | 7:55 PM |
Mark M. |
OK, first, what is the nature of the class? Is this an activity? A fragment? A view? Something else?
|
Tad F. |
Base class is ListActivity
|
Tad F. |
Classes that extend this do something different with their "list".
|
Tad F. |
i.e. list of contacts, list of playlists, etc.
|
Tad F. |
ContactListActivity, PlaylistListActivity, etc.
|
Mark M. |
so, your abstract class extends ListActivity, and you have a subclass that extends the base class
|
Tad F. |
Abstract class *is* ListActivity
|
Tad F. |
The other classes extend that
|
Tad F. |
ListActivity provides basic list management, causes items selected to be in a different color, etc.
|
Mark M. |
so, you have your own class named ListActivity?
|
Mark M. |
(and you're not referring to the ListActivity framework class?)
|
Tad F. |
That's correct
|
Mark M. |
ah, OK
|
Tad F. |
It's a basic Master-Detail framework
|
Tad F. |
It's actually modeled somewhat after what you get when you ask for a Master-Detail activity and Android generates it for you.
|
Tad F. |
I just tweaked that (quite a bit)
|
Mark M. |
yeah, I tried creating something like that 6-7 years ago and put it aside
|
Tad F. |
It uses this layout
|
Tad F. |
View paste
(22 more lines)
|
Tad F. |
(partial file obviously)
|
Tad F. |
That last line is the problem child
|
Mar 3 | 8:00 PM |
Mark M. |
what's in it that needs to differ between your normal scenario and this one special scenario?
|
Tad F. |
In the special scenario I don't want the layout to differ when the width is greater than 600dp
|
Tad F. |
Actually - I do want it to differ - but only in one special case
|
Tad F. |
But I'll set that aside for a sec
|
Mark M. |
yeah, well, I think you're digging yourself a deeper hole
|
Mark M. |
but, let's do set that aside
|
Mark M. |
and let me try restating your situation:
|
Mark M. |
you have layout/item_list.xml and layout-w600dp/item_list.xml
|
Tad F. |
Right
|
Mark M. |
and in this special scenario, you basically do not want layout-w600dp/item_list.xml to be considered
|
Tad F. |
Mostly right, but let's assume that for now
|
Mark M. |
that feels like Miracle Max and "mostly dead", but yeah, let's get to your next complexity later :-)
|
Tad F. |
heh
|
Mark M. |
you might somehow be able hack what you want with layout alias resources, but I am skeptical
|
Mark M. |
oh, no, wait, that won't even help here
|
Tad F. |
The deal is, this base layout is what I want for everything else. Seems silly to copy the whole thing over to a new file just to change that one line.
|
Tad F. |
(which is what I'm doing at the moment)
|
Mar 3 | 8:05 PM |
Mark M. |
well, you could aim to move as much as possible out of the base layout into other <include>'d layouts, so item_list.xml is mostly a mashup, and your replacement for this scenario is a different mashup
|
Tad F. |
Yeah - I was hoping there could be some sort of "classname qualifier" or "custom qualifier" I could invoke
|
Mark M. |
not really
|
Mark M. |
you could see if ViewStub could help: https://developer.android.com/reference/android...
|
Mark M. |
I have never used it, but it offers a setter for the layout resource to use
|
Mark M. |
that way, you could choose to replace the layout resource at runtime that gets inflated in place of the stub
|
Mark M. |
at least, in theory
|
Mark M. |
but, otherwise, I don't have a good solution for you
|
Tad F. |
Hmmm...ok I'll look into that. I suppose I could make an abstract method in ListActivity getDesiredLayout() that each class has to return, and all but MediaListActivity would return item_list.
|
Tad F. |
In case it is a layout that has qualifiers, would it then respect those qualifiers?
|
Mark M. |
or, have a non-abstract getDesiredLayout() method, where ListActivity returns the default
|
Tad F. |
Or do I now need to create a item_list_wide?
|
Tad F. |
Yeah, right
|
Tad F. |
I'm doing that now for some other methods
|
Mark M. |
if by "it" in "would it then respect" is a ViewStub, it should respect those qualifiers
|
Tad F. |
OK I'll look into that, thanks.
|
Mar 3 | 8:10 PM |
Mark M. |
basically, it's just hiding a bit of the LayoutInflater hassle for you, AFAICT
|
Mark M. |
using LayoutInflater directly yourself would be another candidate solution, I suppose
|
Tad F. |
Like, inflate it myself and add it to the parent view?
|
Mark M. |
yeah, particularly if that FrameLayout wrapping your <include> has nothing else in it
|
Mark M. |
give that FrameLayout an ID and inflater.inflate(getDesiredLayout(), yourFrameLayout)
|
Tad F. |
Well it does, but it's one other container - a ConstraintLayout that has a bunch of stuff in it. But the good news, is that EITHER item_list or "empty_list" is made visible. Never both at the same time (one is a layout to use when there is nothing in the list, the other shows 1..N items in a list and various buttons, etc.)
|
Mark M. |
yeah, that should not be a problem
|
Mark M. |
the one headache with inflate() is that the inflated stuff gets added after all current children
|
Tad F. |
So actually it would be to get a reference to the FrameLayout, and then dynamically add either the item_list or what have you as another child.
|
Mark M. |
right
|
Tad F. |
That's ok. It doesn't actually matter in this case which child is first, since only one of the two will be visible at a time.
|
Mark M. |
agreed
|
Mark M. |
basically, <include> itself is a fairly simple, inflexible thing
|
Tad F. |
OK I think dynamically adding the child is the way to go.
|
Mar 3 | 8:15 PM |
Tad F. |
Now back to the little wrinkle :)
|
Mark M. |
it shouldn't be a ton of code, in the end
|
Mark M. |
(wrinkles aside)
|
Tad F. |
So this MediaListActivity extends ListActivity like all the others.
|
Tad F. |
What it does is shows the media list, in four different ways - but all use the same RecyclerView.
|
Tad F. |
I adjust the layoutmanager, adapter and holder based on the "mode" the user is in.
|
Tad F. |
It's like a Gallery where you can first scroll through CardView to select the year you want (with a few photos from that year in a StaggeredLayoutManager)
|
Tad F. |
Or you can view by Month, or by Week
|
Tad F. |
All those work the same, and I don't need the master-detail layout
|
Tad F. |
Just the list
|
Tad F. |
But if the user selects "all" mode, then you get the same list approach that all the other ListActivity derived classes use
|
Tad F. |
So in that case, I'm back to needing to use item_list.xml, including the qualifier to have master-detail panes
|
Tad F. |
on devices with widths >= 60dp
|
Tad F. |
600dp
|
Mark M. |
isn't that a matter of making the detail portion have visibility GONE when you are in modes other than "all"?
|
Tad F. |
Well, there are a couple of other components in that layout (a FAB, a few other items) that allows the user to add/delete from the list. I suppose I could manage those as well to GONE when not in "all" mode.
|
Mar 3 | 8:20 PM |
Mark M. |
they aren't all in a common container representing the detail area?
|
Mark M. |
(and, even if they aren't, but they are all in a ConstraintLayout, use Group)
|
Tad F. |
No - there are effectively two FAB items here when in master-detail mode. On the left, there is one to add to the list. There can also be one on the right, because a single list "item" can actually have detail that needs to be added to it. A playlist for example has its own "one-to-many" relationship with the media items it "owns"
|
Tad F. |
So in the base class, I tried to abstract that out
|
Tad F. |
And let the detail pane handle showing/not showing that FAB.
|
Tad F. |
I suppose if I just don't show the entire detail panel I can manage that...off the top of my head it still seems there was some other reason I was thinking I needed a separate layout, but I don't know remember why
|
Tad F. |
I'll have to look at that.
|
Tad F. |
Maybe you're right - I can just get away with making it GONE
|
Mark M. |
that seems like it should be a reasonably straightforward solution, if perhaps a trifle clunky
|
Tad F. |
Yeah - I'm already starting to see a bit too much of "if this condition then" creeping in...
|
Mark M. |
you may need to consider adopting strategy patterns, rather than relying purely on ListActivity to handle all scenarios
|
Mar 3 | 8:25 PM |
Mark M. |
so, a subclass supplies one (or more) strategy objects that control how some of this stuff gets handled, and ListActivity largely delegates to the strategy objects
|
Tad F. |
Yes, I had started looking into something like that - more composition patterns though.
|
Mark M. |
same basic thing -- think of how RecyclerView handles things like adapters, item decorators, layout managers, etc.
|
Tad F. |
Yes, exactly.
|
Tad F. |
OK - thanks for your insight, as always!
|
Mark M. |
happy to help!
|
Tad F. |
And stay healthy there on the east coast!
|
Mark M. |
thanks, you too!
|
Mar 3 | 8:30 PM |
Mark M. |
OK, that's a wrap for the chat!
|
Mark M. |
the next one is Thursday at 8am US Eastern
|
Mark M. |
have a pleasant evening!
|
Tad F. | has left the room |
Mark M. | turned off guest access |