I have a simple collapsingToolbarLayout xml, like the following:
<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/profile_coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="#dimen/collapse_navbar"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginBottom="#dimen/expandedTitleMarginBottom"
app:expandedTitleMarginEnd="#dimen/expandedTitleMarginEnd"
app:expandedTitleMarginStart="#dimen/expandedTitleMarginStart"">
<ImageView
android:id="#+id/img"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
app:layout_collapseMode="parallax" />
<android.support.v7.widget.Toolbar
android:id="#+id/anim_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:layout_collapseMode="pin"/>
</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"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="24dp">
<!--SOME CONTENT-->
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_anchor="#id/appbar"
app:layout_anchorGravity="bottom|right|end"
android:src="#drawable/ic_mail_white"
android:layout_margin="#dimen/fab_margin"
android:clickable="true"/>
</android.support.design.widget.CoordinatorLayout>
Everything works fine, until I try to scroll from BOTTOM to TOP quickly (from the Nested Scroll View content to the CollapsingToolbarLayout) and the nested content goes over the image, and that's horrible. I have been trying all the options that I've found but nothing seems to work.
All my libraries are updated according to the docs and the base code comes from some basic examples that seems to work fine for everyone.
Can anybody help me with this issue?
I provide some images to explain better the problem:
Normal and correct content before scroll
When scrolling from nested to toolbar
I've finally understood the problem. You're code is correct, the real problem it's your device. I've tested the code you posted on my LG Nexus 5 and everything was fine. Here's a screenshot of my test application:
As you can see, the scroll works fine, and the cards don't overlap the toolbar. Finally yesterday I had the opportunity to test my code on your's phone model, Huawei P8 Lite. And here's the incredible result:
Apparently, this Huawei phone model (or maybe other models too, i don't know) has a strange bug that creates this overlap issue when using the CollapsingToolbarLayout.
The strangest thing is that I searched everywhere on the internet, but I couldn't found anything related to this annoying Huawei bug.
To solve this problem, I suggest that you write personally to Huawei or.. to change phone!
Related
I have a layout that contains a tree of views like below:
- ConstraintLayout
-- TextView
- WebView
- TabLayout (1) (3 tabs)
- ViewPager (1)
- TabLayout (2) (4 tabs)
- ViewPager (2)
When user scrolls to ViewPager (1), TabLayout (1) will stick at top and able to interact like below GIF in Huobi app. And if user scrolls more to ViewPager (2), it will push TabLayout (1) out and TabLayout (2) will be sticked on top.
I tried some articles like (https://stackoverflow.com/a/44327350 -- It creates fake view and not able to interact header) and libs like (https://github.com/emilsjolander/StickyScrollViewItems -- quite too long no update) but i don't feel it good.
Any good practice on this? I see many apps used it but not sure will Google supports it natively and not sure what I missed.
Any help would be appreciated. Thanks.
Update 13/12/2021
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/background_color">
// Header
<include
android:id="#+id/layout_header"
layout="#layout/layout_header" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="#+id/wvChart"
android:layout_width="match_parent"
android:layout_height="#dimen/webview_height" />
<com.google.android.material.tabs.TabLayout
android:id="#+id/tl1"
android:layout_width="match_parent"
android:layout_height="#dimen/tablayout_height"
style="#style/TabLayoutStyle"
app:layout_constraintTop_toBottomOf="#id/wvChart"
app:tabTextAppearance="#style/TabLayoutTextStyle"/>
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/vpg1"
android:minHeight="#dimen/viewpager_market_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/background_color"
app:layout_constraintTop_toBottomOf="#id/tl1"/>
<com.google.android.material.tabs.TabLayout
android:id="#+id/tl2"
android:layout_width="match_parent"
android:layout_height="#dimen/tablayout_height"
style="#style/TabLayoutStyle"
app:layout_constraintTop_toBottomOf="#id/vpg1"
app:tabTextAppearance="#style/TabLayoutTextStyle"/>
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/vpg2"
android:minHeight="#dimen/viewpager_market_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/background_color"
app:layout_constraintTop_toBottomOf="#id/tl2"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</layout>
I am currently using this lib StickyScrollView, it works as expected but contains minor bugs. I still want to find other stable way. Thanks.
As I had no source code from you, I just started to make an own little project to achieve that. First of all you need to take a CoordinatorLayout as base frame. In that you use an AppBarLayout that is the parent of a CollapsingToolbarLayout and in that you can put your content (here e.g. TextView). The second Toolbar in it needs to be pinned (app:layout_collapseMode="pin")
Below that you will continue with the NestedScrollView to have no glitches etc., for a smooth UX.
There you go with your activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.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"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="150dp"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="#6200EA"
app:layout_scrollFlags="scroll|snap|exitUntilCollapsed"
app:title="Collapsing Toolbar">
<TextView
android:layout_width="250dp"
android:layout_height="40dp"
android:layout_gravity="center|end"
android:layout_marginBottom="15dp"
android:scaleType="centerCrop"
android:text="Trade your Bitcoins here:"
android:textSize="18sp"
android:textStyle="bold"
app:layout_collapseMode="parallax" />
<Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Collapsed Toolbar:
Extended Toolbar:
I think now you should have a good inspiration how to design further. It's the same principal. In terms of time I just made a ruff version. In your shown GIF it's just an additional Toolbar at the top, that's normally known as "DarkActionbar" in themes.xml. And the RecyclerView (in your example "Order Book") will be added as a child in NestedScrollView. Cheers!
I'm trying to have a collapsing toolbar view with two snapping point. Is there any way to do this. I'm trying for two days and couldn't find a proper solution. I want something like this:
**
Default look:
**
**
First snapping point:
**
**
Second snapping point:
**
I think you know how to set up a Collapsing Toolbar right?
If you have done that you can get two snapping points with just setting the scroll flags as follows:
<android.support.design.widget.CollapsingToolbarLayout
...stuff...
app:layout_scrollFlags="scroll|enterAlways|snap">
If that doesn't work for you, I found a great post that provides a custom scrolling behaviour. Cheers
So after reading a lot of stack question's and find out their solution has a lot of complex code(and I'm so lazy) for this simple task. I fond a simple solution:
this is my collapsing tollbar layout:
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appBar"
android:layout_width="match_parent"
android:layout_height="258dp"
android:background="#android:color/transparent"
android:fitsSystemWindows="true"
android:minHeight="60dp"
app:elevation="0dp"
app:layout_insetEdge="top">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="#+id/collapsingToolbarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="#android:color/transparent"
app:layout_scrollFlags="scroll|enterAlways|snap">
**/**** First snapping point ***************/**
<com.google.android.material.appbar.MaterialToolbar
android:id="#+id/toolbarOne"
android:layout_width="match_parent"
android:layout_height="70dp"
app:layout_collapseMode="pin" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
for the first snapping point you can use a toolbar with layout_collapseMode="pin" and set the size that you want for the snap position.
now for the second snapping point in your content layout witch have a nested scroll view or whatever, you can use a transparent view with the size you want for second snap position. this will avoid the app bar to rich the scroll rang and you have second snap point:
<androidx.core.widget.NestedScrollView 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/nestedScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/fragment_calendar">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
**/**** second snapping point ***************/**
<ImageView
android:id="#+id/daily"
android:layout_width="match_parent"
android:layout_height="60dp"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
style="#style/PageBackground.White"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/daily"
android:background="#drawable/background_top_corner_calendar">
your content.....
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
I'm using the following layout and it works great on all versions except Android Nougat where the title gets cut off when fully collapsed.
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="300dp"
android:fitsSystemWindows="true"
app:contentScrim="#color/them_color"
app:expandedTitleTextAppearance="#android:color/transparent"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:id="#+id/header_image"
android:layout_width="match_parent"
android:layout_height="300dp"
android:contentDescription="#string/app_name"
android:fitsSystemWindows="true"
android:scaleType="fitXY"
app:layout_collapseMode="parallax"/>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
app:layout_collapseMode="pin"
app:contentInsetLeft="0dp"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
</android.support.design.widget.CollapsingToolbarLayout>
I have tried app:collapsedTitleGravity="center" but it doesn't fix the issue. How can I make it work on Nougat?
Issue is reported.
There is even better option than removing fitsSystemWindows,
just add to onCreate collapsingToolbarLayout.post { collapsingToolbarLayout.requestLayout() }
removing android:fitsSystemWindows="true"
solved my problem
This Sample project shows how to implement collapsing toolbar in Android.
Posting requestLayout in a runnable didn't work for me but if you're using AppCompatActivity you can use setSupportActionBar with the toolbar which seems to work.
Hi i am not sure why this is not working also not sure if this is possible but here is what i am trying to do.
I have a SimpleDraweeView which is contained inside a collapsingtoolbarlayout and i am trying to load an image into it.
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:titleEnabled="false"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<com.facebook.drawee.view.SimpleDraweeView
android:id="#+id/cover_image"
android:layout_width="match_parent"
app:layout_collapseMode="parallax"
android:layout_height="300dp"
fresco:placeholderImageScaleType="centerCrop"
android:fitsSystemWindows="true"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="#55000000"/>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
app:layout_scrollFlags="scroll"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="#style/AppTheme.PopupOverlay"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
and i am trying to set the image in my onCreate method like this.
//gallery is my object which contains coverImage field
Uri coverImageUri = Uri.parse(gallery.getCoverImage());
SimpleDraweeView coverImageView = (SimpleDraweeView)findViewById(R.id.gallery_cover_image);
Toast.makeText(this,gallery.getCoverImage(),Toast.LENGTH_SHORT).show();
coverImageView.setImageURI(coverImageUri);
I am able to see the url in the toast but the image doesn't seem to appear. Any pointers are appreciated.Thanks.
I tried out your code and its all working fine. Your xml is ok and your java code is sound, so i guess that your problem is a simple one. I think you forgot to add the internet permission because thats the only case that didn't display the image for me, just add <uses-permission android:name="android.permission.INTERNET"/> in your manifest.xml and you'll be set.
Also I saw that you have a placeHolderScaleType and not a placeholder, so it would be a good practice to add on if you're loading images online.
And thanks for the shadowed View that you have, it actually gave me a hint to something that i wanted to do and was thinking of ways to do it.
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