Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CollapsingToolbarLayout not collapsing when softkeyboard is visible

I have a layout that I use for my toolbars;

<?xml version="1.0" encoding="utf-8"?>
<merge
 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="wrap_content">

 <android.support.design.widget.AppBarLayout
     android:id="@+id/appbar_layout"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:fitsSystemWindows="true">

    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/expanded_collapsing_toolbar"
        android:layout_width="match_parent"
        android:layout_height="120dp"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">

        <android.support.v7.widget.Toolbar
            android:id="@+id/expanded_toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_collapseMode="pin"/>

    </android.support.design.widget.CollapsingToolbarLayout>

</android.support.design.widget.AppBarLayout>

And I use this in my layouts as;

<com.dan.finance.ui.ExpandedToolbar
    android:id="@+id/expandable_toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:toolbarNavColor="?attr/NavigationIconColor"
    app:toolbarNavIcon="?attr/NavigationUpArrow"
    app:toolbarTitle="My Finances"
    app:toolbarTitleColor="?attr/NavigationTitleColor"/>

And below this in most of my layouts I have a nested scrollview, my problem is on layouts where the content shouldn't scroll by default, opening the soft keyboard allows the content to scroll using adjustResize, but my toolbar doesn't react to this and collapse as it should.

The full code for my layout is;

<?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"
    xmlns:tools="http://schemas.android.com/tools">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.CoordinatorLayout
            android:id="@+id/coordinator_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fillViewport="true">

            <com.dan.finance.ui.ExpandedToolbar
                android:id="@+id/expandable_toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:toolbarNavColor="?attr/NavigationIconColor"
                app:toolbarNavIcon="?attr/NavigationUpArrow"
                app:toolbarTitle="My Finances"
                app:toolbarTitleColor="?attr/NavigationTitleColor"/>

            <android.support.v4.widget.NestedScrollView
                android:id="@+id/nested_scrollview"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fillViewport="true"
                app:layout_anchor="@id/expandable_toolbar"
                app:layout_anchorGravity="bottom"
                app:layout_behavior="@string/appbar_scrolling_view_behavior">

                <android.support.constraint.ConstraintLayout
                    android:id="@+id/container"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">

                <android.support.v7.widget.AppCompatTextView
                    android:id="@+id/title"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:paddingStart="32dp"
                    android:paddingEnd="0dp"
                    android:text="Finances"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent"/>

                <android.support.v7.widget.AppCompatEditText
                    android:id="@+id/edit_text"                       
                    android:layout_width="0dp"
                    android:layout_height="56dp"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                   app:layout_constraintTop_toBottomOf="@id/title"/>

                <android.support.v7.widget.AppCompatTextView
                    android:id="@+id/details"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:text="DETAILS TODO"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toBottomOf="@id/edit_text"/>

                <android.support.v7.widget.RecyclerView                                                      android:id="@+id/finances_list"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal"
                    app:layoutManager="android.support.v7.widget.LinearLayoutManager"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toBottomOf="@id/details"/>

                <android.support.v7.widget.AppCompatButton
                    android:id="@+id/button_see_all"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="See All"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintTop_toBottomOf="@id/finances_list"
                    app:layout_constraintVertical_bias="1.0"/>

                </android.support.constraint.ConstraintLayout>

            </android.support.v4.widget.NestedScrollView>

        </android.support.design.widget.CoordinatorLayout>

    </RelativeLayout>

This layout as a whole doesn't scroll on large devices, but may scroll on smaller devices/future releases so I believe this may be where my problem lies but I've tried quite a few different things and nothing has come up. I've also tried programatically expanding and collapsing the toolbar using

mAppBarLayout.setExpanded(expand, true);

but this doesn't animate the layout I'm assuming because it's not in a scrolling layout because there's no content to bring up maybe?

like image 869
Daniel Sims Avatar asked Apr 04 '19 09:04

Daniel Sims


2 Answers

AppBarLayout must be a direct child of CoordinatorLayout for scrolling and collapsing of the layout to work as you expect. (See AppBarLayout documentation.)

This view depends heavily on being used as a direct child within a CoordinatorLayout. If you use AppBarLayout within a different ViewGroup, most of it's functionality will not work.

Here is what your layout looks like as currently coded. (This is from the Layout Inspector.)

enter image description here

As you can see, AppBarLayout is not a direct child of CoordinatorLayout but is a child of ExpandedToolbar which is, in itself, an AppBarLayout.

To fix this, you will need to change expanded_toolbar.xml to the following:

<?xml version="1.0" encoding="utf-8"?>
<merge 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="wrap_content">

    <!--<android.support.design.widget.AppBarLayout-->
    <!--android:id="@+id/appbar_layout"-->
    <!--android:layout_width="match_parent"-->
    <!--android:layout_height="wrap_content"-->
    <!--android:fitsSystemWindows="true">-->

    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/expanded_collapsing_toolbar"
        android:layout_width="match_parent"
        android:layout_height="120dp"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">

        <android.support.v7.widget.Toolbar
            android:id="@+id/expanded_toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_collapseMode="pin" />

    </android.support.design.widget.CollapsingToolbarLayout>

    <!--</android.support.design.widget.AppBarLayout>-->
</merge>

As you can see, I have removed AppBarLayout by commenting it out. Now, when we run the app, we see the following hierarchy:

enter image description here

Here, you can see that ExpandedToolbar which is really an AppBarLayout is a direct child of the CoordinatorLayout. This works. Here is a visual. I didn't implement the entire custom layout - just enough for demo purposes.

enter image description here

Here is the updated main layout:

activity_main.xml

<RelativeLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.CoordinatorLayout
        android:id="@+id/coordinator_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true">

        <com.example.customviewtoolbar.ExpandedToolbar
            android:id="@+id/expandable_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:toolbarNavColor="?attr/NavigationIconColor"
            app:toolbarNavIcon="?attr/NavigationUpArrow"
            app:toolbarTitle="My Finances"
            app:toolbarTitleColor="?attr/NavigationTitleColor" />

        <android.support.v4.widget.NestedScrollView
            android:id="@+id/nested_scrollview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">

            <android.support.constraint.ConstraintLayout
                android:id="@+id/container"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <android.support.v7.widget.AppCompatTextView
                    android:id="@+id/title"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:paddingStart="32dp"
                    android:paddingEnd="0dp"
                    android:text="@string/finances"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />

                <android.support.v7.widget.AppCompatEditText
                    android:id="@+id/edit_text"
                    android:layout_width="0dp"
                    android:layout_height="56dp"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toBottomOf="@id/title" />

                <android.support.v7.widget.AppCompatTextView
                    android:id="@+id/details"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:text="DETAILS TODO"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toBottomOf="@id/edit_text" />

                <android.support.v7.widget.RecyclerView
                    android:id="@+id/finances_list"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal"
                    app:layoutManager="android.support.v7.widget.LinearLayoutManager"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toBottomOf="@id/details" />

                <android.support.v7.widget.AppCompatButton
                    android:id="@+id/button_see_all"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="See All"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintTop_toBottomOf="@id/finances_list"
                    app:layout_constraintVertical_bias="1.0" />

            </android.support.constraint.ConstraintLayout>

        </android.support.v4.widget.NestedScrollView>

    </android.support.design.widget.CoordinatorLayout>

</RelativeLayout>

As a side note, I removed the anchor-related tags and android:fillViewport="true" from the NestedScrollView since they are not really needed and prevented the layout inspector from working.

You could always just not use the custom view, but I assume that you want it for convenience.

Here is the mock-up of ExpandedToolbar that I used for demo purposes.

ExpandedToolbar.java

public class ExpandedToolbar extends AppBarLayout {
    public ExpandedToolbar(Context context) {
        super(context);
        init();
    }

    public ExpandedToolbar(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
        TypedArray a = context.getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.MyToolbar,
                0, 0);

        try {
            String title = a.getString(R.styleable.MyToolbar_toolbarTitle);
            ((Toolbar) findViewById(R.id.expanded_toolbar)).setTitle(title);
        } finally {
            a.recycle();
        }
    }

    private void init() {
        inflate(getContext(), R.layout.expanded_toolbar, this);
    }
}
like image 121
Cheticamp Avatar answered Oct 21 '22 18:10

Cheticamp


I used code lines are below in the xml file and it worked this way with both softkeyboard is visible and gone

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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.support.design.widget.CoordinatorLayout
            android:id="@+id/coordinator_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fillViewport="true">

        <android.support.design.widget.AppBarLayout
                android:id="@+id/appbar_layout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:fitsSystemWindows="true">

            <android.support.design.widget.CollapsingToolbarLayout
                    android:id="@+id/expanded_collapsing_toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="120dp"
                    app:layout_scrollFlags="scroll|exitUntilCollapsed">

                <android.support.v7.widget.Toolbar
                        android:id="@+id/expanded_toolbar"
                        android:layout_width="match_parent"
                        android:layout_height="?attr/actionBarSize"
                        app:layout_collapseMode="pin"/>

            </android.support.design.widget.CollapsingToolbarLayout>

        </android.support.design.widget.AppBarLayout>

        <android.support.v4.widget.NestedScrollView
                android:id="@+id/nested_scrollview"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fillViewport="true"
                app:layout_anchor="@id/appbar_layout"
                app:layout_anchorGravity="bottom"
                app:layout_behavior="@string/appbar_scrolling_view_behavior">

            <android.support.constraint.ConstraintLayout
                    android:id="@+id/container"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">

                <android.support.v7.widget.AppCompatTextView
                        android:id="@+id/title"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:paddingStart="32dp"
                        android:paddingEnd="0dp"
                        android:text="Finances"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent"/>

                <android.support.v7.widget.AppCompatEditText
                        android:id="@+id/edit_text"
                        android:layout_width="0dp"
                        android:layout_height="56dp"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toBottomOf="@id/title"/>

                <android.support.v7.widget.AppCompatTextView
                        android:id="@+id/details"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:text="DETAILS TODO"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toBottomOf="@id/edit_text"/>

                <android.support.v7.widget.RecyclerView
                        android:id="@+id/finances_list"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:orientation="horizontal"
                        app:layoutManager="android.support.v7.widget.LinearLayoutManager"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toBottomOf="@id/details"/>

                <android.support.v7.widget.AppCompatButton
                        android:id="@+id/button_see_all"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="See All"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintTop_toBottomOf="@id/finances_list"
                        app:layout_constraintVertical_bias="1.0"/>

            </android.support.constraint.ConstraintLayout>

        </android.support.v4.widget.NestedScrollView>

    </android.support.design.widget.CoordinatorLayout>

</RelativeLayout>

Also you can check in your activity AppBarLayout collapse/expand process with this listener:

appbar_layout.addOnOffsetChangedListener(object : AppBarLayout.OnOffsetChangedListener {
            override fun onOffsetChanged(p0: AppBarLayout?, p1: Int) {
                if (Math.abs(p1) - appbar_layout.totalScrollRange == 0) {
                    Log.d("tag", "Collapsed")
                } else {
                    Log.d("tag", "Expanded")
                }
            }
        })

I think it cause because of you're using AppBarLayout in a custom xml.

like image 25
Ozgur Avatar answered Oct 21 '22 19:10

Ozgur