Programmatically show Toolbar after hidden by scro

2019-02-16 15:12发布

问题:

I have the following layout: a drawer, with the main content view having a AppBarLayout, RecyclerView and a TextView. When I scroll the recycler, the toolbar is correctly hidden.

However, I have a use case: when all items from the recycler are removed, I sets its visibility to 'gone' and a TextView with an appropriate message it shown instead. If this is done while the toolbar is hidden, it is not possible for the user to see the toolbar again.

Is it possible to programmatically cause the toolbar to be fully shown? I would do this whenever the TextView is shown instead of the RecyclerView.

Here is my layout:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    android:id="@+id/drawer_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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="true">

    <android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?android:attr/actionBarSize"
                app:layout_scrollFlags="scroll|enterAlways"/>

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

        <android.support.v7.widget.RecyclerView
            android:id="@+id/test_list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="vertical"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

        <TextView
            android:id="@+id/empty_test_list_info_label"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:padding="@dimen/spacing_big"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:visibility="gone"/>

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

    <RelativeLayout
        android:layout_width="280dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="?android:attr/windowBackground"
        android:elevation="10dp"/>

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

BTW, for some reason, if I put the AppBarLayour after the RecyclerView, as all tutorials seem to show it, it hides the topmost item from the list. It only works correctly when it is above it.

回答1:

You can do it by accessing to the AppBarLayout that contains your Toolbar

Here is an example:

if (mToolbar.getParent() instanceof AppBarLayout){
  ((AppBarLayout)mToolbar.getParent()).setExpanded(true,true);
}

setExpanded(expand,animation) will do the work. You can also have a a reference to the AppBarLayout instead of call the getParent from the toolbar.



回答2:

U could either do toolbar.transitionY(int y); on the on scroll method or use visibility gone and u have to add an header in the list view or recycler view with the size of the toolbar. So that the whole list still shows



回答3:

You need to put header to the RecyclerView to the height of the AppBarLayout. I.e at position 0 of the RecyclerView you need to add the header and then the rest of the elements.

If you want to forcefully show the Toolbar, actually the AppBarLayout with offsetting top and bottom of the AppBarLayout dependent views (it is called Behavoir) . You need to keep reference of height of the AppBarLayout, as we know that height is the distance between top and bottom of view Rect.

Assuming that your AppBarLayout hold only a Toolbar:

int mAppBarLayoutHeight = mAppBarLayout.getBottom() - mAppBarLayout.getTop(); //initial, normal height

 private void showToolbar(){
        if(this.mAnimator == null) {
            this.mAnimator = new ValueAnimator();
            this.mAnimator.setInterpolator(new DecelerateInterpolator());
            this.mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                 int animatedOffset = (int) animation.getAnimatedValue();
                 mToolbar.offsetTopBottom(animatedOffset/2);
                }
            });
        } else {
            this.mAnimator.cancel();
        }

        this.mAnimator.setIntValues(0, mAppBarLayoutHeight);
        this.mAnimator.start();
    }