Office Hours — Today, May 9

Thursday, May 7

May 9
3:50 PM
Mark M.
has entered the room
Mark M.
turned on guest access
4:00 PM
Kai H.
has entered the room
Mark M.
hello, Kai!
how can I help you today?
Kai H.
Hello Mark!
Is it common to include ConstraintLayouts in a ConstraintLayout? Say I have four custom buttons that are the same but the content, for example.
Mark M.
by "custom buttons", do you mean a custom view that happens to use a ConstraintLayout as a base?
Kai H.
Yes
Mark M.
there are two main scenarios in which I see nested ConstraintLayouts
Kai H.
(Follow-up question: Should a ConstraintLayout be used for such a custom button or something else).
Mark M.
one is yours: you are using custom views that happen to have a ConstraintLayout base
personally, I avoid custom views to the greatest extent possible, as I find them overly complex for little additional benefit
4:05 PM
Mark M.
as to whether yours needs a ConstraintLayout, that would depend on what's inside it: 2+ items needing positioning, then ConstraintLayout probably is fine
the other nested ConstraintLayout scenario is where the inner ConstraintLayout has some distinct visual property, like a background
conversely, if the nested ConstraintLayout is just positioning stuff, you can probably get rid of it with the right set of attributes on its former children, to get them in the right spots in the outer ConstraintLayout
Kai H.
My first approach was non-nested, but I wanted to get around having to change attributes on all the children every time I changed their look.
Mark M.
use a custom style for the button
and apply it with the style attribute (style="@style/YourCustomButtonStyle")
Kai H.
Does the style include positioning too?
Mark M.
no, but that is not part of their look
at least in terms of how I define "look", anyway
4:10 PM
Kai H.
Because my "Button" is pretty much a square with a picture, a text and a (hidden) "line element" that shows which of the buttons is activated.
Mark M.
depending on circumstances, you could perhaps just do that with <include>
Kai H.
And I was playing around with where the picture and the text should go quite a bit. That would have been quite bothersome if I didn't use include and then have only one place to change things.
I would prefer not to nest it, but I don't wanna repeat myself (DRY).
Mark M.
a custom view for what you are doing here sounds reasonable
and having a nested ConstraintLayout in this situation also seems reasonable
personally, for just four buttons, I would not bother -- 40 or 400, now a custom view is going to be pretty essential
but if you want a custom view at that threshold of reuse, go right ahead
the warnings about nested ConstraintLayout is more for developers migrating to them from nested LinearLayouts
there is nothing intrinsically wrong with nested ConstraintLayouts, so long as there is a clear need for them
the idea is that, compared to LinearLayout, there are fewer use cases for nested ConstraintLayouts
yours (custom views) is one of those use cases
4:15 PM
Kai H.
My "Buttons" are more like "fields" to chose one of four possible mutually exclusive ways to go ahead. They are also my own implementation of RadioButton, as 1) the original RadioButton didn't display my image to my satisfaction and 2) RadioGroup doesn't allow a Grid view, only linear.
Mark M.
yeah, RadioGroup is not particularly flexible
Kai H.
I have a linear layout for horizontal and vertical on big screens and a 2x2 grid for vertical on small screens.
4:20 PM
Kai H.
"linear layout" = ordered the buttons in a line
Mark M.
um, OK
in some scenarios, LinearLayout is still OK to use (avoid nesting and avoid android:layout_weight for best performance)
Kai H.
I meant that I use ConstraintLayout but have the buttons in a line in all cases but "portrait on small screens", in which I use a 2x2 grid :D
Mark M.
OK
Kai H.
It's hard to experess oneself
Mark M.
again, if there's a good reason to nest ConstraintLayouts, that's fine -- we just have fewer reasons to do so than we did in the old LinearLayout days
so, I wouldn't worry about it
Kai H.
How do you generally solve the case of "reusable layouts"?
Mark M.
frankly, in most of my work, I don't have many that aren't already supplied by somebody else (e.g., Material Components for Android, other third-party libraries)
4:25 PM
Mark M.
I don't even think about the problem unless the reuse is significant, either some really complex thing that gets reused a few times or something simpler (like your button) that gets reused a ton
Kai H.
So you try and succeed to stick to standard layouts as much as possible?
Mark M.
yes
on the whole, the designers that I have worked with have stuck with a Material Design-ish foundation
Kai H.
Now I wonder if all the custom layouts and nesting is a sign of using android components wrong.
Mark M.
in the end, you need to implement what the designers ask for
if you are designing it yourself, then you can "dial in" your complexity as you see fit
so, in your button example, there isn't anything in the Android SDK that probably matches, and it's very likely that there isn't an existing third-party solution
so, rolling a custom view is not unreasonable, particularly if that button will be used a lot
4:30 PM
Kai H.
We do have designers, but the app isn't very high priority, so I would say they aren't completely aware of how things are done in the Android realm. I usually make and take suggestions and try to defend things that are really hard to implement.
Mark M.
that's not uncommon
Kai H.
Btw, the idea of my "RadioButtons" are similar to this example: https://stackoverflow.com/a/55422560/6399743
Mark M.
OK
if I had 40 of those spread throughout the app, I'd probably "bite the bullet" and create a custom view
Kai H.
And if you had one of those?
Mark M.
if it's just those four? I would not bother with a custom view, as the maintenance of the custom view IMHO would be worse than any duplication
Kai H.
So you'd play around with one of the buttons until it matches what you want, then change the values of the others regarding?
Mark M.
more or less
I'd probably use a common TextAppearance style for the text
and I'd use dimension resources for the margins/padding between the elements
4:35 PM
Mark M.
and a single StateListDrawable with two vectors for the rounded rectangle borders
and so on
for this, you can go a long way with just sharing those sorts of resources to minimize duplication
Kai H.
That is interesting input
Mark M.
now, that's just how I would do it, and I *think* my approach is pretty common in current Android app development
creating custom views just never was a common part of the Android development experience
it's doable but not the sort of thing you do often
other GUI toolkits take different approaches
Kai H.
I don't have that much experience, which is why it's interesting to hear.
Mark M.
and there it might just second nature to create something reusable for even limited scenarios like this one
Kai H.
Where wouldn't you use ConstraintLayout btw?
Mark M.
if I need just a background around one widget (but where the background extends beyond the widget boundaries), I'd just use a FrameLayout
there are various specialty areas, such as RemoteViews for app widgets, where ConstraintLayout isn't available, so there you have to use legacy solutions
4:40 PM
Mark M.
I suspect that there may still be a scenario or two where TableLayout can do something that ConstraintLayout can't
otherwise, for my personal needs, ConstraintLayout is my go-to solution
Kai H.
ok
Another question if I may?
Mark M.
it's not like I have a crowd today :-)
go right ahead!
Kai H.
I have implemented a custom "list", by just adding views programmatically. By clicking on a list item, a Dialog with an EditText pops up. The result of the Dialog is saved in a ViewModel shared by the Dialog and the Fragment with the list.
My problem is that after the dialog is closed the underlying Fragment doesn't know that it needs to redraw the list to make the change visible.
How would I best implement notifying the fragment of the change?
4:45 PM
Mark M.
my default solution would be a ViewModel shared between the fragment and a DialogFragment for your dialog
that ViewModel would have a LiveData that the DialogFragment updates with the results (accept/cancel, contents of the EditText, etc.)
and the parent fragment would observe the LiveData and react on those results
Kai H.
The result of the EditText actually goes into a list of values inside the ViewModel (actually an ArrayList of a custom class which holds the user name, user id, a user note (which is the result of the edit text) etc.).
So the parent Fragment would have to actually observe this list, right?
Mark M.
presumably, yes, if I understand your scenario correctly
4:50 PM
Kai H.
As those custom users classes are in a certain order, right now I have getUserNote(int index) and getUserName(int index) and call those to populate the list. The list is not returned directly.
That makes things a bit harder
I might just switch to RecyclerView instead of having my own custom list :D
Mark M.
that also adds flexibility (e.g., automatic scrolling for smaller screens)
Kai H.
I find RecyclerView a bit hard to wrap my head around
Mark M.
lots and lots and lots of examples of it across my books :-)
Kai H.
It has so many parts that are needed, especially if things like drag and drop are wanted too
Mark M.
seems like half of my newer samples are based on a RecyclerView
Kai H.
I read the one in "exploring jetpacks"
Twice actually. It's just... a lot of parts just to get something simple going
Mark M.
well, yes, but implementing drag and drop in your own hand-rolled list isn't going to be a picnic, either
Kai H.
And understanding what goes where and stuff
I just used arrows on the list items X)
Mark M.
I agree that it has a higher floor of difficulty than I'd like
Kai H.
In the case of having a Dialog with an EditText inside like above, who would listen to what for the RecyclerView to get updated on a change?
4:55 PM
Mark M.
if I understand your scenario correctly, you have a fragment with the RecyclerView, and it is displaying a dialog with an EditText in certain scenarios
if so, I would try to have a shared ViewModel between the parent and dialog fragments
Kai H.
Yes, if I click on a button on one of the list items.
Mark M.
the parent would observe a LiveData in that shared ViewModel to find out the results of the dialog
the parent could then do whatever is needed with those results, which might be to tell its own private ViewModel about some data change
Kai H.
Oh, now I understand.
So you'd have two ViewModels, instead of just one like I have right now.
Mark M.
right
Kai H.
I really liked my solution with having just one ViewModel for everything ;-)
Would it be bad design to only have one ViewModel?
And maybe have a field for the EditText in there that can be observed for change, so the parent Fragment(s) get notified when a change has happened?
Mark M.
I would not do it that way -- encapsulation is fairly important for maintainability and testability
Kai H.
I see
Mark M.
the parent fragment should not have access to widgets from the child fragment, and vice versa
Kai H.
I understand.
5:00 PM
Kai H.
Than kyou
Mark M.
and that's a wrap for today's chat
Kai H.
Have a good time
Mark M.
next one is Tuesday at 7:30pm US Eastern
Kai H.
And stay healthy
Mark M.
you too! on both counts! :-)
Kai H.
has left the room
Mark M.
turned off guest access

Thursday, May 7

 

Office Hours

People in this transcript

  • Kai Hatje
  • Mark Murphy