I am making my TabLayout animated by using android:animateLayoutChanges="true" in AppBarLayout. But when I set TabLayout.setVisibility(View.GONE), container for my fragment goes up to ActionBar instantly for a few milliseconds. And then it returns to the end of TabLayout and goes up with it to the ActionBar. I explained this on following gif.
The buttons Theory and Practice are behind the TabLayout for some reason but when hiding TabLayout animation starts FrameContainer that holds my view sticks to the bottom of TabLayout.
I have recorded a video that demostrates this behavior. Dropbox video player skip some frames and animation seems nice. Thats why, to notice the bug, you can load video on computer and watch 5 and 11 second in high quality. Video
My LayoutXML:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<SurfaceView
android:layout_width="0px"
android:layout_height="0px"/>
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:visibility="gone"
app:tabGravity="fill"
app:tabIndicatorColor="#android:color/white"
app:tabMode="fixed"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<!--
This FrameLayout holds my fragments.
-->
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/outer_background">
<ProgressBar
android:id="#+id/main_load_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:indeterminate="true"/>
</FrameLayout>
<include
android:id="#+id/left_drawer_full"
layout="#layout/navigation_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"/>
</android.support.v4.widget.DrawerLayout>
</android.support.design.widget.CoordinatorLayout>
In addition I am using 23.2.1 support libraries.
How can I fix this blinks and jumps?
Try adding android:animateLayoutChanges="true" to your view with
app:layout_behavior="#string/appbar_scrolling_view_behavior
so that would be your DrawerLayout. Then enable Transition Type LayoutTransition.CHANGING on it like so:
ViewGroup layout = (ViewGroup) findViewById(R.id. drawer_layout);
LayoutTransition layoutTransition = layout.getLayoutTransition();
layoutTransition.enableTransitionType(LayoutTransition.CHANGING);
related: https://stackoverflow.com/a/22573099/1363742
I wasted all day to investigate this problem.
And I have found one possible solution for this problem.
Now i change visibility by this code
mTabLayout.postDelayed(new Runnable() {
#Override
public void run() {
switch (newMode) {
case MODE_CONTENTS:
mTabLayout.setVisibility(mContents.isTheoryAvailable() ? View.VISIBLE : View.GONE);
break;
default:
findViewById(R.id.content_frame).setVisibility(View.INVISIBLE);
mTabLayout.setVisibility(View.GONE);
findViewById(R.id.content_frame).setVisibility(View.VISIBLE);
}
}
}, 200);
It works well and views are not blinking now. But on old androids the bug is still presents.
Related
The new BottomNavigationView from support library v25.0.0 is supposed to hide when scrolling down, in order to see all the items from a list. However, in my testing scenario, the view hides when scrolling up. Any ideas what can cause this reverse behavior?
The inner_fragment is set up as a Fragment inserted inside the activity_main_framelayout_content Framelayout. XML layouts below:
main_activity.xml:
<android.support.design.widget.CoordinatorLayout
android:id="#+id/activity_main_coordinatorlayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/activity_main_appbarlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/activity_main_toolbar"
android:layout_height="?attr/actionBarSize"
android:layout_width="match_parent"
android:background="?attr/colorPrimary"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:layout_scrollFlags="scroll|enterAlways">
<include layout="#layout/activity_main_spinner_layout"/>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/activity_main_framelayout_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:fitsSystemWindows="true"/>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="#+id/activity_main_framelayout_navigation_drawer"
android:layout_width="#dimen/drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
android:background="#color/color_black_700"/>
inner_fragment.xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/inner_fragment_framelayout"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<android.support.design.widget.BottomNavigationView
android:id="#+id/inner_fragment_bottom_navigation_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:menu="#menu/inner_fragment"
app:itemBackground="#drawable/bg_bottom_navigation"
app:itemIconTint="#color/ic_bottom_navigation"
app:itemTextColor="#color/ic_bottom_navigation"/>
</FrameLayout>
A simple solution is to just add an offset listener to appbarlayout. Works perfectly for me.
So something like this:
((AppBarLayout)toolbar.getParent()).addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
mNavigationBar.setTranslationY(verticalOffset*-1);
}
});
This release of BottomNavigationView is missing scrolling behavior to work out of the box as specified in the guidelines.
I wrote an article on what's missing and how you can fix it. This includes implementing scrolling behavior of the BottomNavigationView in CoordinatorLayout.
My solution was to replace the FrameLayout with a NestedCoordinatorLayout from here https://stackoverflow.com/a/37660246/2233621 and then add the BottomNavigationBehavior from Nikola's blog post https://medium.com/#nullthemall/bottomnavigationview-missing-pearls-eaa950f9ad4e#.p1i01wwui that way your bottom navigation behaviour can listen for nested scrolling of the fragment inside the NestedCoordinatorLayout
I believe you could use another view that implements NestedScrollParent + NestedScrollChild for the same behaviour.
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"
In my application I have an issue where I want to have high level navigational control from a navigation drawer, and page level control within a TabLayout within a fragment. This however causes issues with the shadow rendering from the AppBar onto the fragment.
Here's the basics of what my layouts and code does. At the root I have this simple layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:fitsSystemWindows="true"
tools:context=".MainAppActivity">
<android.support.design.widget.AppBarLayout android:layout_height="wrap_content"
android:layout_width="match_parent" android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar android:id="#+id/toolbar"
android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary" app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_main" />
</android.support.design.widget.CoordinatorLayout>
When my navigation drawer is selected I inflate the fragment into "content_main"
this.getSupportFragmentManager()
.beginTransaction()
.addToBackStack(tag)
.replace(R.id.content_main_layout, fragment, tag)
.commit();
The fragment being put into content_main contains a layout with my TabView and a view pager:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_github_issues"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="#+id/github_issues_tab_layout"
android:layout_height="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_gravity="top"
android:background="?attr/colorPrimary"
android:theme="#style/AppTheme.AppBarOverlay"/>
<android.support.v4.view.ViewPager
android:id="#+id/github_issues_viewpager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
What's the a good best practice to fix the issue? Is including TabLayout to live within the top level AppBar and just disabling the view based on the page an acceptable implementation?
First you need to change the view hierarchy to something like this:
FrameLayout
-CoordinatorLayout -> content
-Toolbar
Fix Toolbar elevation to be exact with the AppBarLayout, too get rid of the shadow but keep the z-order of the Toolbar:
int appBarLayoutElevation = ViewCompat.getElevation(mAppBarLayout);
getActivity().getSupportActionBar().setElevation(appBarLayout);
Similar example I have worked in my blog post.
I have a classic layout with a ToolBar on the top, a TabLayout below it, and a ViewPager switching tabs from the TabLayout. When content in the ViewPager is scrollable, the ToolBar should scroll out of sight, and the TabLayout should follow and stick when it reaches the top.
All this is good in my current code, except, the ToolBar is always scrollable, regardless of the size of the ViewPager's content. See my code below. Any brilliant ideas on how to fix this?
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/primary"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.ToolBar"
app:layout_scrollFlags="scroll|enterAlways" />
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:scrollbars="horizontal"
app:tabIndicatorColor="#color/black_text" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/tabs_activity_view_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
EDIT:
I can see that the viewPager's height is the same as the height for the entire root view. This might be intentded, as the appbar_scrolling_view_behavior does seem to add a top and bottom offset. It does however seem weird, since it will result in always scrolling the toolbar and tabbar.
I have solved the issue, tried over the example Google template and find out that
app:layout_behavior="#string/appbar_scrolling_view_behavior"
line must be added into view pager properties xml. It solved my problem.
I suggested you try this sample.
this is a layout like your layout in the sample.
<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/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<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.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:layout_scrollFlags="scroll|enterAlways" />
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="#dimen/fab_margin"
android:src="#drawable/ic_done" />
</android.support.design.widget.CoordinatorLayout>
using ListView as the data for ViewPager? If so, you need listView.setNestedScrollingEnabled(true);
Try adding these attributes on TabLayout:
app:layout_collapseMode="pin"
app:tabMode="fixed"
And this on AppBarLayout:
android:fitsSystemWindows="true"
* UPDATE *
I tried and this is not enough, since toolbar is still scrollable.
The solution is to make some logic about ViewPager (and its content).
Remove from xml layout file the toolbar scroll_flag attribute.
You have to implement some java code to check if ViewPager content height is > then screenHeight - (toolbar + tabBar). If true, set programmatically the scroll_flags as this:
LayoutParams params;
params = // get layout params from your toolbar
params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
| AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS);
// set params
toolbar.setLayoutParams(params);
Based on other samples, my own code, and the (somewhat messy) source code of the appbar_scrolling_view_behavior:
public boolean onDependentViewChanged(CoordinatorLayout parent, View child,
View dependency) {
final CoordinatorLayout.Behavior behavior =
((CoordinatorLayout.LayoutParams) dependency.getLayoutParams()).getBehavior();
if (behavior instanceof Behavior) {
// Offset the child so that it is below the app-bar (with any overlap)
final int appBarOffset = ((Behavior) behavior)
.getTopBottomOffsetForScrollingSibling();
final int expandedMax = dependency.getHeight() - mOverlayTop;
final int collapsedMin = parent.getHeight() - child.getHeight();
if (mOverlayTop != 0 && dependency instanceof AppBarLayout) {
// If we have an overlap top, and the dependency is an AppBarLayout, we control
// the offset ourselves based on the appbar's scroll progress. This is so that
// the scroll happens sequentially rather than linearly
final int scrollRange = ((AppBarLayout) dependency).getTotalScrollRange();
setTopAndBottomOffset(AnimationUtils.lerp(expandedMax, collapsedMin,
Math.abs(appBarOffset) / (float) scrollRange));
} else {
setTopAndBottomOffset(dependency.getHeight() - mOverlayTop + appBarOffset);
}
}
return false;
}
I'm reading this in a way explaining the problem, as this is expected behavior with this code.
I think we need to write our own scroll behavior, specially for the RecyclerView,
The ViewPager height should be match_parent and not wrap_content.
i've just had the same problem.
The solution is very simple, just set your viewpager height
android:layout_height="wrap_content"
Simple solution is
- wrap your appbar layour and page viewer with a relative layout.
- give your appbar layout some id
- in page view set android:layout_below="Your_appbar_layout"
Eg:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/your_appBar_ID"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/primary"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.ToolBar"
app:layout_scrollFlags="scroll|enterAlways" />
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:scrollbars="horizontal"
app:tabIndicatorColor="#color/black_text" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/tabs_activity_view_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/your_appBar_ID"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</RelativeLayout>
I want to achieve something like that. (not the FAB or the Snackbar). How can i create a layout, overlaying the AppBarLayout? Like this! (For Example)
Like Play Store:
My AppBarLayout with CoordinatorLayout and NestedScrollView with RelativeLayout as content looks like this:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="#dimen/_118sdp"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsingToolbarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="#color/mpc_pink"
app:expandedTitleMarginStart="#dimen/_40sdp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<de.mypostcardstore.widgets.ItemImageView
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="#color/mpc_pink"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.7" />
<android.support.v7.widget.Toolbar
android:id="#+id/article_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:minHeight="?attr/actionBarSize"
app:contentScrim="#color/mpc_pink"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:colorBackground"
android:fillViewport="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<RelativeLayout
android:layout_width="match_parent".....>
It would be awesome if someone could help me out. I can not find anything on the internet...
Thanks in advance!
Just add something like
app:behavior_overlapTop="64dp"
to your NestedScrollView and it will be placed above the expanded toolbar.
In addition, you should add something like
app:expandedTitleMarginBottom="70dp"
to your CollapsingToolbarLayout so the title does not appear under your overlaid scroll content.
It's quite simple, really. You could achieve that by using a combination of ToolBar, FrameLayout, and your content view (could be a ListView like your first example, or anything).
The idea is to make your FrameLayout possess the same color as your ToolBar, giving the illusion of ToolBar being much larger than it is. Then all that is left to do is to make your content view be the last (or in API 21 and above: possess the highest elevation attribute) so that it would appear as if it floats above the aforementioned FrameLayout.
See my illustration below:
Now that you got the big idea, below is some real live XML snippet for doing such thing. (I actually use this layout in one of my apps) :
<!-- Somewhere in your layout.xml -->
....
<android.support.v7.widget.Toolbar
android:id="#+id/tb_toolbar"
android:layout_width="match_parent"
android:layout_height="#dimen/abc_action_bar_default_height_material"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:contentInsetStart="72dp"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<!-- This is the 'faux' ToolBar I've been telling you about. This is the part that will be overlaid by the content view below. -->
<FrameLayout
android:id="#+id/v_toolbar_extension"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_below="#+id/tb_toolbar"
android:background="?attr/colorPrimary"
android:elevation="2dp"/>
<!-- Normally, I use this FrameLayout as a base for inflating my fragments. You could just use put your content view here. -->
<FrameLayout
android:id="#+id/ly_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/tb_toolbar"
android:elevation="3dp"/>
....
Note that my ly_content has higher elevation value than that of v_toolbar_extension. This is what will give you that desired 'overlaid toolbar' effect.
Last but not least, you would want to add this line somewhere in your activity's onCreate() :
/* Assuming mToolbar exists as a reference to your ToolBar in XML. */
setSupportActionBar(mTbToolbar);
getSupportActionBar().setElevation(0);
What that codes woud do is to set your ToolBar elevation to zero; removing preset shadows that were given as a default to ToolBars. If you don't do this, said shadow will create a "seam" between your ToolBar and your FrameLayout, thus breaking the illusion of those two being the same.
p.s., It is also important to give your content view a padding on each side. Doing so, your content view will not cover the entire width of the screen (which would render this effect useless).
Note: I see some good answers here that mentioned the absence of FrameLayout and instead making the ToolBar taller. While in theory it might work as well as my proposed solution, you might have problems when trying to manipulate scrolling; by doing that, you won't be able to separate ToolBar and its extension. You'll be forced to either make the Toolbar static or scroll all of the ToolBar altogether (makes scrolling a bit weird).
Add to that, the fact that you can't easily assign a custom drawable into a Toolbar. Hence makes it hard to follow the Google Play example you've given above. While if you're using my solution, all you'd need to do is just make your Toolbar transparent and assign the drawable to the FrameLayout instead.
I had a similar requirement and I achieved it as below.
Your activity theme should extend Theme.AppCompat.Light.NoActionBar.
I created a Layout XML File as:
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar_main"
android:layout_width="match_parent"
android:layout_height="#dimen/action_bar_size_x2"
android:background="#color/colorPrimary"
android:minHeight="?attr/actionBarSize" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="#dimen/action_bar_size"
android:orientation="vertical" >
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="#string/app_name"
android:textSize="24sp" />
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
And the Activity should be something like this:
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar maintoolbar = (Toolbar) findViewById(R.id.toolbar_main);
setSupportActionBar(maintoolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
}
I got a view like this :
I did try to implement effects like you referred which is called Card Toolbar in Android, and it did work as expected. Here is my layout, Take a look at it:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/background_material_light" >
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="#dimen/toolbar_double_height"
android:background="?attr/colorPrimary" />
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="#dimen/cardview_toolbar_spacer"
android:layout_marginRight="#dimen/cardview_toolbar_spacer"
android:layout_marginTop="?attr/actionBarSize"
app:cardBackgroundColor="#android:color/white">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:alpha="0.12"
android:background="#android:color/black" />
</LinearLayout>
</android.support.v7.widget.CardView>
</FrameLayout>
Hope you'll be inspired.