My client requested a collapsing view (triggered by a recycler view) that doesn't graphically belong to AppBar / Toolbar abstraction. While I was able to fake it somehow with the mentioned view sitting really inside CollapsingToolbarLayout, I really feel the code is clumsy and will be a nightmare to maintain.
The name CoordinatorLayout suggests that maybe the collapsing / parallax behaviour could be used anywhere in view hierarchy, but I couldn't find neither example nor any proof of in Android docs. All examples show collapsing views only inside AppBars!
So - is it or is it not possible to collapse any view anywhere with events from some RecyclerView?
Since it was requested - a schematic view of the layout. But the question is really more general. As stated above - I've implemented it putting the collapsable square inside AppBar and setting background to white. It works as required, but looks hacky...
I really feel the code is clumsy and will be a nightmare to maintain.
I don't think so.
Also CollapsingToolbarLayout is optional (Remember, you can use minHeight if you want).
But you have to keep AppBarLayout to get things worked. (Don't forget to set app:elevation="0dp" to the AppBarLayout)
Is it or is it not possible to collapse any view anywhere with events
from some RecyclerView?
Yes, it is possible. By attaching an OnScrollListener to the RecyclerView and manually collapsing it. But I think the AppBarLayout method will be enough for this.
Related
I have a recycler view below my appbar, and it expands when I'm at the top of my RV and I scroll up one more time. I need my collapsed toolbar to expand when the smooth scrolling animation reaches the top, so I don't need to scroll up again. Instead what I get is that I scroll to the top, and my RV stops, then I have to scroll again just to expand the collapsed toolbar.
I am currently looking into MotionLayout, because in this answer I've read it offers easier behavior customization https://stackoverflow.com/a/55328600/13150066
I don't know how to upload videos here, but if you have an idea and want to check out the behavior I want, check out spotify's playlist.
Is there a solution to my problem so I don't have to change to MotionLayout?
I had to take a look at those MotionLayout and it's super easy. Made it work!
I downloaded Android Studio 4.1 so I could use the new layout design interface and it work wonders. Honestly I thought it was going to be really difficult to achieve, this effect, but it was really simple, and everything is pretty self explainatory. Anyways, I'm leaving you the tutorial I did it with, hope it helps!
https://blog.stylingandroid.com/motionlayout-collapsing-toolbar-part-1/
I think the most beneficial part of using MotionLayout is that it extends from ConstraintLayout, so your Layouts are laid flat. No Collapsing Toolbar inside an AppBar, with a Toolbar and an ImageView nested. Using MotionLayout, I only used an imageView laid flat and the animations are set in a new XML.
I am trying to understand how some view works. I start reading the source code of CollapsingToolbarLayout. But i am confused, there is not onTouch function in it whereas we need to touch our screen to expand/collapse the view.
So how CollapsingToolbarLayout can be collapsed/expanded with our finger but there's no onTouch method overrided?
Can somebody explain to me?
This is because onTouch isn't the only way to interact with Views.
For CollapsingToolbarLayout, you first need to understand that it is designed to be used as a child of AppBarLayout.
AppBarLayout is pretty much a vertical LinearLayout that's used to implement lots of features that belong to Material Design, including the scrolling features. In other words, this layout is what handles the scrolling for the child View.
In the source of CollapsingToolbarLayout, look at the onAttachedToWindow() method. Inside this method, you'll see that if the parent of this toolbar is an AppBarLayout, then it'll set a custom-defined OffsetUpdateListener into it's parent's addOnOffsetChangedListener() method. Look further down the source to see the definition of it's OffsetUpdateListener.
What this does is CollapsingToolbarLayout is telling it's parent (AppBarLayout) to tell itself if there are any changes to the 'offset' which is the scrolling.
So there's no need for CollapsingToolbarLayout to have an 'OnTouch' override, because it doesn't handle the touches or scrolling. It simply allows it's parent to handle the scrolling while it just tells the parent to let it know when it should react, in other words... when it should collapse or expand.
they use OnOffsetChangedListener which is an interface definition for a callback to be invoked when an AppBarLayout's vertical offset changes.
onOffsetChanged Called when the AppBarLayout's layout offset has been changed. This allows child views to implement custom behavior based on the offset (for instance pinning a view at a certain y value).
here is the reference OnOffsetChangedListener
Basically, CollapsingToolbarLayout is not a View but ViewGroup. It inherits from FrameLayout and acts as container for AppBarLayout when some of view needed to be collapsed/expanded based on app bar's scrolling behavior.
So, it's a wrapper for Toolbar which implements a collapsing app bar. It is designed to be used as a direct child of a AppBarLayout.
Now for your question :
"So how CollapsingToolbarLayout can be collapsed/expanded with our finger but there's no onTouch method overrided?"
Answer is simple, it doesn't. It's the AppBarLayout itself which intercepts touch event based on OffsetChange listener and passes callbacks to it's descendants. CollapsingToolbarLayout has ability to animate toolbar title (collapse/expand) and some other stuffs like scriming background, pinning title etc. so, basically it responds to AppBarLayout's OffsetChange listener when callbacks received.
Check out official reference for more details.
I am trying to create an activity layout with two parts, where their respective size is dynamic. The activity should have two states:
Starting state:
The user scrolls the bottom part up to the second state (and back):
It's important that the change will be animated. I tried a few solutions so far but didn't manage to find the exact way to do that:
AndroidSlidingUpPanel - The panel acts as another layout, covering the upper view and moving the toolbar out of the screen.
Android Split Pane Layout - Correct behavior, but the splitter is dragged and not the bottom part (I don't want to have a visible splitter).
CoordinatorLayout with CollapsingToolbarLayout - I didn't find a way to limit the upper part from totally disappearing. Anyway I think that it's a bit abusing because I don't want to collapse a toolbar but just change the children's height with animation.
Is there a good way to implement this using another library, one of these that I perhaps didn't use correctly or with simple layouts? Thanks!
I found a custom version of the SlidingPaneLayout created by VLC, which is basically a vertical SlidingPaneLayout - the exact functionality that I was looking for.
I've been using Phonograph music player for a while and it's a really good looking app in my opinion. It has a very nice sort of header: basically there's the toolbar wich slides up and down along with the recycler view hiding behind the status bar when scrolling down and coming back visible when scrolling up, the difference with other toolbars show/hide animations is that this one does not actually have two rigid states (hidden or shown) but instead it can be half covered, 70% covered, 80% covered and so on, it moves at the same speed of the recycler view, it's really different than the ActionBar.hide() .
Little clip to explain what I'm talking about:
http://i.imgur.com/JCIiFAA.jpg
I've searched the web for solutions but I haven't found nothing close enough but I think that the Observable Scroll View library might be a good starting point (Have already done some testings but so far it has those 2 rigid states wich I don't want).
I am using an activity MainActivity.java and setting its content view to activity_main.xml, how can I achieve that result?
Also how can I make that view pager selector just below the toolbar but sticky?
CoordinatorLayout from Design Support Library is what you are looking for.
See Tutorial here https://mzgreen.github.io/2015/06/23/How-to-hideshow-Toolbar-when-list-is-scrolling(part3)/
First of all you need to wrap up your Layout with Coordinator layout and set this flag on Toolbar
app:layout_scrollFlags="scroll|enterAlways"
I've been experimenting with the new offerings of the library and I just can't wrap my head around customizing it the way I want.
I am taking as a reference this sample code: https://github.com/chrisbanes/cheesesquare
I have successfully managed to add a static fragment (contains some FrameLayout with recyclerView and additional empty views) as the child of the CoordinatorLayout, which works as expected when scrolling the (ugly) recycler view inside it.
The working gist and the result:
I am only trying to add one extra CardView above my fragment, which should also have the same effect on the toolbar when dragged upwards. I tried adding them both to a LinearLayout inside a NestedScrollView, together with other various combinations, of which none was successful. Whenever I tap on the cardview, they are displaced and never again in their own place. Moreover, dragging the cardview still fades out the toolbar, but nothing else happens.
The non-working gist and the result:
I came across a different issue using CoordinatorLayout as the container for my fragments: https://code.google.com/p/android/issues/detail?id=179600
It seems CoordinatorLayout has a number of issues with this use case. The solution is likely to use a FrameLayout instead to contain your fragment, then put the CoordinatorLayout as the top level container of your fragment's UI.