Android 协调布局:隐藏/显示半可见工具栏?

Android 协调布局:隐藏/显示半可见工具栏?,android,android-toolbar,Android,Android Toolbar,我想实现与您在Google Play store中看到的效果类似的效果,通过滚动内容,工具栏会在滚动时离开屏幕 这与在#io15引入的协调布局(CoordinatorLayout)配合得很好,但是:如果您在“中途”停止滚动,工具栏将保留在屏幕上,但会被切成两半:我希望它在屏幕外设置动画,就像在Google Play商店中一样我如何才能做到这一点?活动布局文件: <FrameLayout xmlns:android="http://schemas.android.com/apk/re

我想实现与您在Google Play store中看到的效果类似的效果,通过滚动内容,
工具栏
会在滚动时离开屏幕

这与在#io15引入的
协调布局(CoordinatorLayout
)配合得很好,但是:如果您在“中途”停止滚动,工具栏将保留在屏幕上,但会被切成两半:我希望它在屏幕外设置动画,就像在Google Play商店中一样我如何才能做到这一点?

活动布局文件:

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingTop="?attr/actionBarSize"
        android:clipToPadding="false"/>

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"/>

</FrameLayout>
从RecyclerView.OnScrollListener扩展MyScrollListener

public abstract class MyScrollListener extends RecyclerView.OnScrollListener {

    private static final float TOOLBAR_HIDE_THRESHOLD = 10;
    private static final float TOOLBAR_SHOW_THRESHOLD = 70;

    private int mToolbarOffset = 0;
    private boolean mControlsVisible = true;
    private int mToolbarHeight;
    private int mTotalScrolledDistance;

    public MyScrollListener(Context context) {

        final TypedArray styledAttributes = context.getTheme().obtainStyledAttributes(
                new int[]{R.attr.actionBarSize});
        mToolbarHeight = (int) styledAttributes.getDimension(0, 0);
        styledAttributes.recycle();

        return toolbarHeight;
        mToolbarHeight = Utils.getToolbarHeight(context);
    }

    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);

        if(newState == RecyclerView.SCROLL_STATE_IDLE) {
            if(mTotalScrolledDistance < mToolbarHeight) {
                setVisible();
            } else {
                if (mControlsVisible) {
                    if (mToolbarOffset > TOOLBAR_HIDE_THRESHOLD) {
                        setInvisible();
                    } else {
                       setVisible();
                    }
                } else {
                    if ((mToolbarHeight - mToolbarOffset) > TOOLBAR_SHOW_THRESHOLD) {
                        setVisible();
                    } else {
                        setInvisible();
                    }
                }
            }
        }
    }

        @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        clipToolbarOffset();
        onMoved(mToolbarOffset);

        if((mToolbarOffset <mToolbarHeight && dy>0) || (mToolbarOffset >0 && dy<0)) {
            mToolbarOffset += dy;
        }
        if (mTotalScrolledDistance < 0) {
            mTotalScrolledDistance = 0;
        } else {
            mTotalScrolledDistance += dy;
        }
    }

    private void clipToolbarOffset() {
     if(mToolbarOffset > mToolbarHeight) {
         mToolbarOffset = mToolbarHeight;
       } else if(mToolbarOffset < 0) {
            mToolbarOffset = 0;
        }
    }

    private void setVisible() {
        if(mToolbarOffset > 0) {
            onShow();
            mToolbarOffset = 0;
        }
        mControlsVisible = true;
    }

    private void setInvisible() {
        if(mToolbarOffset < mToolbarHeight) {
            onHide();
            mToolbarOffset = mToolbarHeight;
        }
        mControlsVisible = false;
    }

    public abstract void onMoved(int distance);
    public abstract void onShow();
    public abstract void onHide();
}
公共抽象类MyScrollListener扩展了RecyclerView.OnScrollListener{
私有静态最终浮动工具栏\u隐藏\u阈值=10;
专用静态最终浮动工具栏\u显示\u阈值=70;
私有int mToolbarOffset=0;
私有布尔值mControlsVisible=true;
私人内部mToolbarHeight;
私营企业总收入;
公共MyScrollListener(上下文){
最终类型Darray styledAttributes=context.getTheme().ActainStyledAttributes(
新的int[]{R.attr.actionBarSize});
mToolbarHeight=(int)styledAttributes.getDimension(0,0);
styledAttributes.recycle();
返回高度;
mToolbarHeight=Utils.getToolbarHeight(上下文);
}
@凌驾
CrollStateChanged上的公共无效(RecyclerView RecyclerView,int newState){
super.onScrollStateChanged(recyclerView、newState);
if(newState==RecyclerView.SCROLL\u STATE\u IDLE){
if(MTOtalScrolledInstance工具栏\隐藏\阈值){
设置不可见();
}否则{
setVisible();
}
}否则{
如果((mToolbarHeight-mToolbarOffset)>工具栏\u显示\u阈值){
setVisible();
}否则{
设置不可见();
}
}
}
}
}
@凌驾
已填空的公共空间(RecyclerView RecyclerView、int dx、int dy){
super.onScrolled(recyclerView、dx、dy);
clipToolbarOffset();
未移动(mToolbarOffset);
如果((mToolbarOffset 0)| |(mToolbarOffset>0&&dy mToolbarHeight){
mToolbarOffset=mToolbarHeight;
}否则如果(MTOOLBOROFFSET<0){
mToolbarOffset=0;
}
}
私有void setVisible(){
如果(MTOOLBOROFFSET>0){
onShow();
mToolbarOffset=0;
}
mControlsVisible=true;
}
私有无效设置不可见(){
if(mToolbarOffset
覆盖AppBarLayout似乎是一个更好的解决方案,因为有两个可能的滚动事件-整个CoordinatorLayout和RecyclerView/NestedScrollView

将此答案视为可能的工作代码:

现在,Android支持库23.1.0有了一个新的滚动标志
scroll\u flag\u SNAP
,可以实现这种效果

AppBarLayout支持许多滚动标志,这些标志会影响子视图对滚动的反应(例如,从屏幕上滚动)。此版本的新增功能是SCROLL_FLAG_SNAP,确保在滚动结束时,视图不会部分可见。相反,视图将滚动到最近的边缘,使其完全可见或完全从屏幕上滚动


@zoltish请告诉我这是否适用于您,如果适用,请接受作为答案。:)可以滚动应用程序栏/工具栏,而无需滚动RecyclerView,在这种情况下,将不会触发侦听器代码。当RecyclerView位于顶部并且没有任何东西可以向上滚动时,就会发生这种情况,而用户向下拉,这将导致整个CoordinatorLayout的滚动
public abstract class MyScrollListener extends RecyclerView.OnScrollListener {

    private static final float TOOLBAR_HIDE_THRESHOLD = 10;
    private static final float TOOLBAR_SHOW_THRESHOLD = 70;

    private int mToolbarOffset = 0;
    private boolean mControlsVisible = true;
    private int mToolbarHeight;
    private int mTotalScrolledDistance;

    public MyScrollListener(Context context) {

        final TypedArray styledAttributes = context.getTheme().obtainStyledAttributes(
                new int[]{R.attr.actionBarSize});
        mToolbarHeight = (int) styledAttributes.getDimension(0, 0);
        styledAttributes.recycle();

        return toolbarHeight;
        mToolbarHeight = Utils.getToolbarHeight(context);
    }

    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);

        if(newState == RecyclerView.SCROLL_STATE_IDLE) {
            if(mTotalScrolledDistance < mToolbarHeight) {
                setVisible();
            } else {
                if (mControlsVisible) {
                    if (mToolbarOffset > TOOLBAR_HIDE_THRESHOLD) {
                        setInvisible();
                    } else {
                       setVisible();
                    }
                } else {
                    if ((mToolbarHeight - mToolbarOffset) > TOOLBAR_SHOW_THRESHOLD) {
                        setVisible();
                    } else {
                        setInvisible();
                    }
                }
            }
        }
    }

        @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        clipToolbarOffset();
        onMoved(mToolbarOffset);

        if((mToolbarOffset <mToolbarHeight && dy>0) || (mToolbarOffset >0 && dy<0)) {
            mToolbarOffset += dy;
        }
        if (mTotalScrolledDistance < 0) {
            mTotalScrolledDistance = 0;
        } else {
            mTotalScrolledDistance += dy;
        }
    }

    private void clipToolbarOffset() {
     if(mToolbarOffset > mToolbarHeight) {
         mToolbarOffset = mToolbarHeight;
       } else if(mToolbarOffset < 0) {
            mToolbarOffset = 0;
        }
    }

    private void setVisible() {
        if(mToolbarOffset > 0) {
            onShow();
            mToolbarOffset = 0;
        }
        mControlsVisible = true;
    }

    private void setInvisible() {
        if(mToolbarOffset < mToolbarHeight) {
            onHide();
            mToolbarOffset = mToolbarHeight;
        }
        mControlsVisible = false;
    }

    public abstract void onMoved(int distance);
    public abstract void onShow();
    public abstract void onHide();
}