Let's say we have a BottomNavigationBar with a FAB on top. When using this setup and showing a Snackbar, the Snackbar should appear above the BottomNavigationBar and push up/down the FAB while appearing/dismissing.
This is a common scenario for the use of CoordinatorLayout. Is it also possible to create this animation using the new MotionLayout?
There is an issue in the bug tracker, but it's already closed, because OP didn't clearly formulate the question (https://issuetracker.google.com/issues/112665540)
Problems I ran into while trying: We don't have access to the layout-id of the Snackbar. We also don't have access to the general xml of the Snackbar, so we cannot set its Constraints.
UPDATE: I understand that a piece of code would help as a starting point to answer this question. But what ever piece of code I came up with yet, was not useful at all. I pinpointed now the 2 main problems:
I do not know the layout-id of the Snackbar. Therefore I cannot use it in writing a Scene description.
Even if I could create a Scene description (e.g. State1: SnackBar visible, State2: Snackbar not visible). I'd have to trigger these Scene transitions by hand. That means that I would re-create my own Snackbar instead of using the original Snackbar as it is intended.
COMMENTS: #mikejonesguy Yes, in my opinion they are similar. Not the same, but similar. And MotionLayout does also have the job you described: to coordinate interactions among its subviews. Replace "coordinate" with "animate" and you'll see my point. Also have a look at the OnSwipe/OnClick handlers. MotionLayout is still very fresh, but I think it will replace CoordinatorLayout in the future the same way ConstraintLayout replaced RelativeLayout. Maybe I'm wrong, maybe not...time will tell.
CONCLUSION:
As far as I'm concerned, there seems to be no way (yet) to achieve what I want only by using MotionLayout. If it's possible one day, I'll update this question with a working example. Sorry for the impossible bounty... :)
You can design your layout files as if the snackbar is in your layout hierarchy. You need to make use of Constraintlayout's virtual helper objects. Virtual objects are invisible but they act as a regular view during measuring & layout, therefore their purpose is to help you create the exact positioning you want.
A snackbars default height is min 48dp and max 80dp. You are going to need this information.
Related
Recently, I've been working on a chat UI, in which I have some custom component, an EditText mainly, for the user to write the message on. The first image would be an example layout, not necessarily the one I'm using, but the concept is the same. The other two images, are the current state of the UI, and what I would like to achieve.
FYI, this is a Fragment, within an Activity, which has a BottomNavigation component. I make this clarification, because, should I just apply the windowSoftInputMode="adjustResize" I'm afraid the BottomNavigation component will also appear above the keyboard, as would the button.
So I'm guessing the question is: how do I tell the keyboard to stay below the entire EditText? Is this even possible? That's my main concern.
Thanks!
After going down the rabbit hole quite a bit, I basically found three approaches:
Using ViewTreeObserver.OnGlobalLayoutListener, mentioned in the question ADM provided above, which in turn, refers to this post here.
Taking advantage of this library, which for many, seemed to do the trick.
Finally, the one I've seen the least out there. For devices with API level 30, or above, you can use the following piece of code to listen to changes in keyboard visibility. It is described in full, with many other useful new things, here:
ViewCompat.setOnApplyWindowInsetsListener(view) { v, insets ->
val imeVisible = insets.isVisible(Type.ime())
// do something with imeVisible value
}
I'm having problems with views not refreshing in MotionLayout.
Seems like at some point the refresh/redraw mechanism of MotionLayout becomes broken and the subviews (including the nested ones) are having random problems updating themselves on the screen. What I have experienced so far:
RecyclerView is not refreshed sometimes. This happens when new data is available, I'm using Paging library to fill the data. I have fixed it with a workaround of scrolling 1 pixel when I got new data there - recyclerView.smoothScrollBy(0,1). After that the RecyclerView starts redrawing itself just fine.
When the keyboard is opened it randomly messes the nested subview redrawing. There is an issue in github โ here where a guy reproduces all this by adding an EditText to official MotionLayout examples. Some examples of the problems that I'm seeing:
I'm using TextInputLayout with app:endIconMode="clear_text" in MotionLayout -> ConstraintLayout -> TextInputLayout and the X button is sometimes not shown when I start typing (also after closing the keyboard).
TextView is redrawn partially! I'm showing "No Results" or "No Posts" text in a TextView, switching between them based on some logic, but instead of refreshing the whole text only "No" is shown in the UI. I have debugged it, Layout Inspector says everything is fine, the text view value is "No Results", but I don't see it on the screen.
Some other animations are broken, like indeterminate progress animation of nested SwipeRefreshLayout
IMPORTANT: All the refresh/redraw issues are fixed when I do a transition! When I come to some messed state where 3 nested subviews are frozen/partially drawn, then I just need to press a button that triggers my transition, and all of them are happily redrawing themselves!
Please let me know if this is a known problem and if there is a workaround for this. I could do invisible 1 pixel transition maybe, but I cannot even detect when the MotionLayout refreshing becomes broken, handling keyboard and new data of RecyclerView doesn't seem to cover all the cases. Otherwise, I will have to move back to ConstraintLayout and think on implementing the amazing OnSwipe functionality myself (if that is even possible in ConstraintLayout).
I am also experiencing issues with update of nested subviews and MotionLayout. Google please fix this issue with MotionLayout.
Using requestLayout() on the nested subviews will often update the Views.
By default during transition motionLayout does not honor requestlayout() during transitions.
Add layoutDuringTransition=honorRequest during the transition
<Transition ... motion:layoutDuringTransition="honorRequest" ... \>
Not really an answer, but too long for a comment:
Since you are facing multiple problem with possibly multiple root causes, I would suggest to create a Sandbox project and reproduce each problem at a time in a safe and simple environment.
To me it seem like you have one problem with the paging lib (not with motionLayout in this case) and another problem with the EditText.
You should check your paging code without ML and check your EditText problem without any scrolling views. I know this is not much of a help, but maybe a guide how to tackle these problems. Mind that MotionLayout is still in beta and especially release 2.0.0-beta02 and beta03 was pretty messy with regression errors. Update to the newest version (beta04 as of now) or continue using a stable version.
Sometimes it also helps to search the official tickets for MotionLayout
I am trying to implement youtube like tabs.
Is there a way to achieve this with CoordinatorLayout, AppBarLayout and TabLayout ?
I already tried to change AppBarLayout height in onScrollListener in fragment, but it is causing some scroll flickering.
Youtube tabs
Definitely there's a way to do it. That's what AppBarLayout was born to do -- stuff like that.
But if you're trying to change the AppBarLayout height in an onScrollListener in a fragment, you have run far afield from the way those components are supposed to work.
Be forewarned that these components are fragile as heck, just barely do what they are supposed to do, are not well documented and they break easily. Doing something like hammering away at the AppBarLayout height would go far beyond "breaks easily", and venture well into the realm of "that's not really how it's supposed to work at all".
Putting the ListView (or RecyclerView) in a fragment may also go horribly wrong for all kinds of fairly obvious reasons relating lifecycle and order of instantiation of views.
I would suggest starting with a working sample for AppBarLayout, and moving your way forward incrementally from there. If you're using Android Studio, right click on your app folder, and select New/Activity/ScrollingActivity, and work your way from there.
Whether you can drive the AppBarLayout from a ListView or RecyclerView in a fragment or not, I couldn't say. I think you should be able to do that; but I'd suggest that you get a dummy listview working as a direct child of the activity first, and then try migrating it to a fragment afterward.
Expect it to be hard. And expect that you'll have to live with limitations of inflexible implementation. They do what they do. And do not like to do what they don't do.
I'm trying to design an app with a layout that will roughly look like this (don't mind the color):
How can I achieve something like that? I'm thinking of using a CardView for that bottom panel (I don't know what it's really called).
Furthermore, I want to hide it (animating it) when the use scrolls on the content. I have tried many codes but they won't work so I won't put them here anyway (like what's suggested here). Thanks for the help.
Whenever I have a question along the lines of "How do I do this neat UI thing I saw once?", I always start by checking out wasabeef's amazing UI library collection. In your case I might start by looking at bottomsheet or AndroidSweetSheet.
Can anyone tell me what control or how do you create the pop-up effect used in these images to display the legend?
The screenshots are taken from an app called FlyOKC.
Any help is greatly appreciated, thank you.
This is not exactly a custom dialog. But, yes it is still a customized view. And it is more or less called Quick Action Dialog in android. I would suggest you to follow the tutorials below for generating an exactly same popover (or even better) with Android. Check the screenshot also.
http://www.londatiga.net/it/how-to-create-quickaction-dialog-in-android/
http://www.androidpatterns.com/uap_pattern/quick-actions (Pattern Reference)
That's certainly using a custom version of a dialog. The idea is to implement your layout in a xml and inflate it in a dialog. There's a lot of tutorials around, try that one.
Actually, that can be achieved by using RelativeLayout and switching the legend view's visible state between View.VISIBLE and View.GONE in button's click handler.
To get the exact animation you'll need to jump some hoops.
Here are related threads:
How does one Animate Layout properties of ViewGroups?
How do I animate View.setVisibility(GONE)
Also, I think another (and possibly easier) way would be to use Fragments API with transition effects, in which case this is the thread to read:
Animate the transition between fragments