I want to programmatically hide / show the TabLayout in my AppBarLayout. Simply setting visibility to VISIBLE and GONE is not enough, as I want to animate the changes and reclaim the space with my content while the tab retreats and leave the space once the tab is shown back.
Below is the relevant part of my layout XML -
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
<android.support.design.widget.TabLayout
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|enterAlways"
app:tabMode="scrollable"
android:layout_marginStart="42dp"
android:layout_marginLeft="42dp"
style="#style/MainTabLayout">
</android.support.design.widget.TabLayout>
</android.support.design.widget.AppBarLayout>
As any ViewGroup subclass, AppBarLayout allows for automatic animations during the adding/removal of child views. You just need to add android:animateLayoutChanges="true" (default to false) in your layout file.
As for reclaiming the space content when the view is gone, all you have to do is use setVisibility(View.GONE) rather than setVisibility(View.INVISIBLE), because the latter holds the space for the invisible view.
Related
In my app, when the keyboard is invoked, the toolbar is moved upwards. How do I prevent the toolbar from moving upwards?
Here's the code to make the activity full screen:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
Layout:
<RelativeLayout xmlns:android=".."
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:layout_alignParentTop="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/toolbar_background">
<include layout="#layout/layout_toolbar" />
</android.support.design.widget.AppBarLayout>
<ScrollView.......>
<RelativeLayout......>
<EditText....><!--There are multiple EditTexts here.-->
</RelativeLayout>
Add this line in menifests for Activity
android:windowSoftInputMode="adjustResize"
add android:fitsSystemWindows="true" in your toolbar's root layout
Most of the time, your app won’t need to draw under the status bar or
the navigation bar, but if you do: you need to make sure interactive
elements (like buttons) aren’t hidden underneath them. That’s what the
default behavior of the android:fitsSystemWindows="true" attribute
gives you: it sets the padding of the View to ensure the contents
don’t overlay the system windows.
A few things to keep in mind:
fitsSystemWindows is applied depth first — ordering matters: it’s the
first View that consumes the insets that makes a difference
from https://medium.com/androiddevelopers/why-would-i-want-to-fitssystemwindows-4e26d9ce1eec
basically you're telling the toolbar not to move & stay on top & instead move the views underneath it upwards below it
You can use a CollapsingToolBarLayout if it fits your UI requirement inside of the AppBarLayout.
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ripple="http://schemas.android.com/apk/res-auto"
android:id="#+id/tv_toolbar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#fff"
ripple:contentInsetStart="0dp">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
I have tried the combination of AppBarLayout and CollapsingToolbarLayout, which doesn't work for this situation. It seems that it only works for a main activity layout. Is it possible to pin the tab layout when scrolling up when it comes to the tab layout which is inside Fragment C? Thanks for your help.
This is a Fragment consisting of Fragment A, Fragment B, Fragment C, Fragment C contains a view pager and tab layout.
Finally, I would like to pin the tab layout on top of the screen when scrolling up.
You can use StickyScrollView https://github.com/emilsjolander/StickyScrollViewItems
<com.kiwkard.views.StickyScrollView
android:id="#+id/sticky_scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:orientation="vertical"
android:tag="sticky-nonconstant">
<android.support.design.widget.TabLayout
android:id="#+id/tab_Layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:tabGravity="fill"
app:tabIndicatorHeight="3dp"
app:tabMode="fixed"
app:tabSelectedTextColor="#color/white"
app:tabTextAppearance="#android:style/TextAppearance.Widget.TabWidget"
app:tabTextColor="#color/black_30"/>
<android.support.v4.view.ViewPager
android:id="#+id/pager_event"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
</com.kiwkard.views.StickyScrollView>
don't forget to give tag attribute in your layout which you want to be fixed, and you can go through to above mentioned link for more tags according to your requirement.
I am trying to create some combined layout using CoordinatorLayout and also CollapsingToolbarLayout.
In the first state, when we on the most top page, and didn't scrolled yet, I want the toolbar to expend as shown below (yes, i did it):
In the second state, when starting to scroll down, the image and toolbar should disappear, as shown below (only tab will show):
And in the last state once I am at some point in the list (but not the top of the list) I want to start scrolling up, once I start scrolling up I want the toolbar (and not the expended one with the image) to start whowing, as shown below (if didn't reaches the top of the list, the image will not show, only the toolbar):
I was able to achive the the first state, but the other 2 state are problematic,
once toolbar is implemented inside CollapsingToolbarLayout, the flexability of what I can do with it outside of CollapsingToolbarLayout component is not clear.
I can't make the toolbar hide, if I do so, then it will only be shown once I reaches the top.
Anyways, my current XML (showing below) is in state where the first picture is implemented, but once I start scrolling down, the toolbar stay at the top and do not hide. Note: I must tell the toolbar to stay "pin" because if I didn't then the information inside the toolbar disappear, and only an empty toolbar will show (that's for another post, but it still interesting to know why this happen?).
here is my current xml:
<android.support.design.widget.CoordinatorLayout
android:id="#+id/benefit_coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar_material_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/main.collapsing"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
>
<include
android:id="#+id/toolbar_search_container"
layout="#layout/search_box"
android:layout_height="192dp"
android:layout_width="match_parent"
app:layout_collapseMode="parallax"
/>
<include
android:id="#+id/toolbar_benefit"
layout="#layout/toolbar_main"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:contentScrim="?attr/colorPrimary"
/>
</android.support.design.widget.CollapsingToolbarLayout>
<android.support.design.widget.TabLayout
android:id="#+id/benefit_tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/primaryColor"
app:tabIndicatorColor="#color/accentColor"
app:tabSelectedTextColor="#android:color/white"
app:tabTextColor="#android:color/black"
app:tabIndicatorHeight="4dp" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/benefit_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<include
layout="#layout/floating_btn_benefits"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_margin="16dp"
/>
</android.support.design.widget.CoordinatorLayou
I have fixed the issue, just to clerify, I wanted my Toolbar to be able to expand with a paralex image once it reaches the top, but I also wanted the toolbar to disappear if scrolling down, and show itself again (without the paralex image) once I scroll up. the paralex image effect should only displayed if I reaches the top.
So basically the solution is, change the component CollapsingToolbarLayout with the following attribute:
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
and also change toolbar component with the following attribute
android:minHeight="?attr/actionBarSize"
regarding my paralex effect image (which is my toolbar_search_container) I shouldn't add any layout_scrollFlags to it.
So why is it working?
To understand it, you need to know what is enterAlwaysCollapsed,
The enterAlwaysCollapsed effects views that added the minHeight attribute. this means, every child of CollapsingToolbarLayout which have minHeight will be effected by this attribute.
So my toolbar will be effected.
enterAlwaysCollapsed attribute definition in simple words:
Assuming enterAlways is declared and you have specified a minHeight, you can also specify enterAlwaysCollapsed. When this setting is used, your view will only appear at this minimum height. Only when scrolling reaches to the top will the view expand to its full height..."
Well, isn't this exactly what we want? (do not answer this retorical question ;) )
One more thing to add, the parallax component (toolbar_search_container) is depends on the toolbar to expand, and because the toolbar will expand only when it reaches the top, then this is all just working great!
The new code is :
<android.support.design.widget.CoordinatorLayout
android:id="#+id/benefit_coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar_material_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/main.collapsing"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
>
<include
android:id="#+id/toolbar_search_container"
layout="#layout/search_box"
android:layout_height="192dp"
android:layout_width="match_parent"
app:layout_collapseMode="parallax"
/>
<include
android:id="#+id/toolbar_benefit"
layout="#layout/toolbar_main"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:minHeight="?attr/actionBarSize"
app:contentScrim="?attr/colorPrimary"
app:layout_collapseMode="pin"
android:fitsSystemWindows="true"
/>
</android.support.design.widget.CollapsingToolbarLayout>
<android.support.design.widget.TabLayout
android:id="#+id/benefit_tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/primaryColor"
app:tabIndicatorColor="#color/accentColor"
app:tabSelectedTextColor="#android:color/white"
app:tabTextColor="#android:color/black"
app:tabIndicatorHeight="4dp" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/benefit_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<include
layout="#layout/floating_btn_benefits"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_margin="16dp"
/>
</android.support.design.widget.CoordinatorLayout>
Add this line of code to your CollapsingToolbarLayout
app:layout_scrollFlags="scroll|snap|enterAlways|enterAlwaysCollapsed"
I have this layout:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways|snap"/>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
</android.support.v7.widget.RecyclerView>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fabButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:src="#drawable/ic_favorite_outline_white_24dp"/>
</android.support.design.widget.CoordinatorLayout>
Setting #string/appbar_scrolling_view_behavior attribute shifts the RecyclerView by the height of the Toolbar.
But what if I need the first element of the RecyclerView to be aligned to the status bar.
I want the Toolbar to cover (be above) the first element.
In other words, I don't want any offset which #string/appbar_scrolling_view_behavior behaviour entails.
Could you please tell me how to do that?
I had the same problem and I just wrapped the AppbarLayout and the rest of my views (in your case the recyclerview) in a RelativeLayout and it works fine. I don't know if there are any downsides with that approach.
The offset is not by #string/appbar_scrolling_view_behavior behaviour it's due to AppBarLayout it pushes the content down.
I'm not sure if there is any other better solution. But I'd suggest to remove the AppBarLayout to have your content go under the Toolbar. Moreover you might be need the scrolling behaviour for that you can check the library below.
It's been used by lots of apps like Jair Music Player even WhatsApp too uses it.
Library:
Android Observable Scroll View
Update
I was looking into this because when I changed the size of the spacer manually it caused stuttering and thought the CollapsingToolbarLayout will help fix it.
Reading https://stackoverflow.com/a/16103503/2482564 help me fix the stuttering by using ObjectAnimator and setting its duration to 0.
I'm keeping the question open in case someone has a solution with CollapsingToolbarLayout
Original question
I'm trying to achieve the following behavior with CoordinatorLayout, AppBarLayout, CollapsingToolbarLayout, Toolbar and TabLayout - whichever is appropriate for the task...
I want my initial view to look like this mockup
and the behavior when scrolling up should be:
the area marked in yellow disappears 1st
the area marked in blue disappears 2nd - it's only an area with color, no text
the area marked in pink - the tabs area, remains on the screen and is located at the top of the screen
I tried to work with the cheesesquare example and modified include_list_viewpager with the code below, but I get the normal collapsing tabs behavior with the shrinking title
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:minHeight="50dp"
android:background="#color/cardview_dark_background"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways|snap"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_marginTop="50dp"
android:background="#color/cardview_shadow_start_color"
android:gravity="top"
android:orientation="vertical"
app:layout_collapseMode="pin">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/cardview_light_background"/>
</LinearLayout>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
any idea what should be changed to get the behavior I want? I tried other methods of changing the size of the spacer area manually, but it causes flickering on screen since I'm intruding in the middle of the scroll event
Remove the app:layout_scrollFlags="scroll|exitUntilCollapsed" from your CollapsingToolbarLayout