May 9 | 3:50 PM |
Mark M. | has entered the room |
Mark M. | turned on guest access |
May 9 | 4:00 PM |
Kai H. | has entered the room |
Mark M. |
hello, Kai!
|
Mark M. |
how can I help you today?
|
Kai H. |
Hello Mark!
|
Kai H. |
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
|
Mark M. |
personally, I avoid custom views to the greatest extent possible, as I find them overly complex for little additional benefit
|
May 9 | 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
|
Mark M. |
the other nested ConstraintLayout scenario is where the inner ConstraintLayout has some distinct visual property, like a background
|
Mark M. |
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
|
Mark M. |
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
|
Mark M. |
at least in terms of how I define "look", anyway
|
May 9 | 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.
|
Kai H. |
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
|
Mark M. |
and having a nested ConstraintLayout in this situation also seems reasonable
|
Mark M. |
personally, for just four buttons, I would not bother -- 40 or 400, now a custom view is going to be pretty essential
|
Mark M. |
but if you want a custom view at that threshold of reuse, go right ahead
|
Mark M. |
the warnings about nested ConstraintLayout is more for developers migrating to them from nested LinearLayouts
|
Mark M. |
there is nothing intrinsically wrong with nested ConstraintLayouts, so long as there is a clear need for them
|
Mark M. |
the idea is that, compared to LinearLayout, there are fewer use cases for nested ConstraintLayouts
|
Mark M. |
yours (custom views) is one of those use cases
|
May 9 | 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.
|
May 9 | 4:20 PM |
Kai H. |
"linear layout" = ordered the buttons in a line
|
Mark M. |
um, OK
|
Mark M. |
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
|
Mark M. |
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)
|
May 9 | 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
|
Mark M. |
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
|
Mark M. |
if you are designing it yourself, then you can "dial in" your complexity as you see fit
|
Mark M. |
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
|
Mark M. |
so, rolling a custom view is not unreasonable, particularly if that button will be used a lot
|
May 9 | 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
|
Mark M. |
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
|
Mark M. |
I'd probably use a common TextAppearance style for the text
|
Mark M. |
and I'd use dimension resources for the margins/padding between the elements
|
May 9 | 4:35 PM |
Mark M. |
and a single StateListDrawable with two vectors for the rounded rectangle borders
|
Mark M. |
and so on
|
Mark M. |
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
|
Mark M. |
creating custom views just never was a common part of the Android development experience
|
Mark M. |
it's doable but not the sort of thing you do often
|
Mark M. |
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
|
Mark M. |
there are various specialty areas, such as RemoteViews for app widgets, where ConstraintLayout isn't available, so there you have to use legacy solutions
|
May 9 | 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
|
Mark M. |
otherwise, for my personal needs, ConstraintLayout is my go-to solution
|
Kai H. |
ok
|
Kai H. |
Another question if I may?
|
Mark M. |
it's not like I have a crowd today :-)
|
Mark M. |
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.
|
Kai H. |
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.
|
Kai H. |
How would I best implement notifying the fragment of the change?
|
May 9 | 4:45 PM |
Mark M. |
my default solution would be a ViewModel shared between the fragment and a DialogFragment for your dialog
|
Mark M. |
that ViewModel would have a LiveData that the DialogFragment updates with the results (accept/cancel, contents of the EditText, etc.)
|
Mark M. |
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.).
|
Kai H. |
So the parent Fragment would have to actually observe this list, right?
|
Mark M. |
presumably, yes, if I understand your scenario correctly
|
May 9 | 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.
|
Kai H. |
That makes things a bit harder
|
Kai H. |
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"
|
Kai H. |
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
|
Kai H. |
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?
|
May 9 | 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
|
Mark M. |
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
|
Mark M. |
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.
|
Kai H. |
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 ;-)
|
Kai H. |
Would it be bad design to only have one ViewModel?
|
Kai H. |
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.
|
May 9 | 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 |