使用 Google 设计库时如何使工具栏卡入视图或隐藏?

Posted

技术标签:

【中文标题】使用 Google 设计库时如何使工具栏卡入视图或隐藏?【英文标题】:How to make the Toolbar snap into view or out of view when using Google Design Library? 【发布时间】:2015-10-28 14:56:30 【问题描述】:

我正在尝试实现类似于 WhatsApp 的效果,工具栏(滚动时)将像磁铁一样剪辑到视图中,或者像磁铁一样在视图外。

我的 MainActivity XML 中有什么:

DrawerLayout - 基本布局 CoordinatorLayout - 应用栏和工具栏和选项卡的布局 AppBarLayout - 用于保存工具栏和选项卡 工具栏 - 有这个标志:app:layout_scrollFlags="scroll|enterAlways" SlidingTabLayout - 显示选项卡 ViewPager - 用于标签 RecyclerView - 用于协调器布局

现在不要误会我的意思,它起作用了,当我向下滚动时,工具栏被推到视野之外,但说我中途停止滚动,然后工具栏就坐在那里,一半隐藏在视野之外,另一半在视野中..

我该如何解决这个问题,因为我希望它要么突然消失,要么进入视线。

【问题讨论】:

这里也一样!我只找到了这个帖子,但我还没有...mzgreen.github.io/2015/06/23/… 【参考方案1】:

此功能已在23.1.0 版本的android 支持库中添加。 来自发行说明:

通过添加 SCROLL_FLAG_SNAP 常量。滚动结束时,如果视图仅 部分可见,视图被捕捉并滚动到最接近的位置 边缘。

<android.support.design.widget.CoordinatorLayout
        android:layout_
        android:layout_>

        <android.support.design.widget.AppBarLayout
            android:layout_
            android:layout_
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

           <android.support.v7.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_
                    android:layout_
                    app:layout_scrollFlags="scroll|enterAlways|snap" />
           -----
           -----

欲了解更多信息:http://android-developers.blogspot.in/2015/10/android-support-library-231.html

【讨论】:

自 23.1.0 Android 设计支持库发布以来,这应该是正确的答案 简单多了!确实,现在应该是正确的答案。 这可行,但为什么 Android Studio 会用红色文本突出显示 snap 标志?然后,当您将鼠标悬停在上面看到警告时,它会显示“无法解析标志”。 @toobsco42 它在我的 android studio 中没有显示任何警告。尝试清理一次项目。 @AbhishekV 你是对的。现在我关闭并重新打开项目后它不会显示警告。【参考方案2】:

编辑:从支持 23.1.0 开始,不再需要此功能。请参阅this answer。

解决此问题的一种可能方法是将Behavior 设置为您的AppBarLayout

<android.support.design.widget.AppBarLayout
    app:layout_behavior="com.myapp.AppBarLayoutSnapBehavior"
    android:layout_
    android:layout_>
    ...

您的AppBarLayoutSnapBehavior 将通过在滚动停止时添加捕捉逻辑来更改AppBarLayout.Behavior 的默认行为。 希望下面的代码是不言自明的。

package com.myapp;

public class AppBarLayoutSnapBehavior extends AppBarLayout.Behavior 

    private ValueAnimator mAnimator;
    private boolean mNestedScrollStarted = false;

    public AppBarLayoutSnapBehavior(Context context, AttributeSet attrs) 
        super(context, attrs);
    

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child,
                                       View directTargetChild, View target, int nestedScrollAxes) 
        mNestedScrollStarted = super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
        if (mNestedScrollStarted && mAnimator != null) 
            mAnimator.cancel();
        
        return mNestedScrollStarted;
    

    @Override
    public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target) 
        super.onStopNestedScroll(coordinatorLayout, child, target);

        if (!mNestedScrollStarted) 
            return;
        

        mNestedScrollStarted = false;

        int scrollRange = child.getTotalScrollRange();
        int topOffset = getTopAndBottomOffset();

        if (topOffset <= -scrollRange || topOffset >= 0) 
            // Already fully visible or fully invisible
            return;
        

        if (topOffset < -(scrollRange / 2f)) 
            // Snap up (to fully invisible)
            animateOffsetTo(-scrollRange);
         else 
            // Snap down (to fully visible)
            animateOffsetTo(0);
        
    

    private void animateOffsetTo(int offset) 
        if (mAnimator == null) 
            mAnimator = new ValueAnimator();
            mAnimator.setInterpolator(new DecelerateInterpolator());
            mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() 
                @Override
                public void onAnimationUpdate(ValueAnimator animation) 
                    setTopAndBottomOffset((int) animation.getAnimatedValue());
                
            );
         else 
            mAnimator.cancel();
        

        mAnimator.setIntValues(getTopAndBottomOffset(), offset);
        mAnimator.start();
    

唯一的是,滚动视图(在我的例子中是 RecyclerView)与 Toolbar 一起捕捉。我其实很喜欢这种方式,但我不确定这是否是你想要的。

【讨论】:

这实际上并没有提供与 whatsapp 样式完全相同的效果。即使在简单的触摸工具栏上也会离开屏幕。并在轻微向下拖动时实际上将工具栏拉下 recyclerview 中的任何位置(滚动位置) 如何让 RecyclerView 不与工具栏对齐?你的解决方案是完美的,除了这一点。【参考方案3】:

我只是在主活动中隐藏了操作栏布局,并为 CollapsingToolbarLayout 设置了跨度。 它对我有用。

在主要活动中

    setSupportActionBar(mToolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);     
    getSupportActionBar().hide();

    CollapsingToolbarLayout collapsingToolbar =
            (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
    collapsingToolbar.setTitle("Name");
    loadBackdrop();

和 layout_activity_main

<android.support.design.widget.AppBarLayout
    android:id="@+id/appbar"
    android:layout_
    android:layout_
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    android:fitsSystemWindows="true">

    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/collapsing_toolbar"
        android:layout_
        android:layout_
        app:layout_scrollFlags="scroll|snap"
        android:fitsSystemWindows="true"
        app:contentScrim="?attr/colorPrimary"
        app:expandedTitleMarginStart="48dp"
        app:expandedTitleMarginEnd="64dp">

        <ImageView
            android:id="@+id/backdrop"
            android:layout_
            android:layout_
            android:scaleType="centerCrop"
            android:fitsSystemWindows="true"
            app:layout_collapseMode="parallax" />

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_
            android:layout_
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_collapseMode="pin" />

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

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

【讨论】:

以上是关于使用 Google 设计库时如何使工具栏卡入视图或隐藏?的主要内容,如果未能解决你的问题,请参考以下文章

视图设计问题:如何使滚动视图的子视图填充屏幕?

如何使 ConstraintLayout 使用百分比值?

Google guava工具类的介绍和使用

Google guava工具类的介绍和使用

arcgis版面视图中怎么修改整张地图背景?

如何使用 drupal 视图使图像流链接到内容或产品