Android L联系人应用如何折叠其工具栏?

时间:2014-10-24 22:15:28

标签: android android-layout android-actionbar android-5.0-lollipop android-toolbar

我一直在尝试重现滚动列表视图时5.0版本上的联系人应用程序折叠工具栏的方式。

Gallery of screenshots demonstrating the desired interaction 请注意工具栏分阶段崩溃,它显示搜索+上次联系,淡化上次联系,折叠上次联系,折叠搜索,只留下选项卡。

到目前为止,我在LinearLayout的Recyclerview上方有一个工具栏,工具栏用作操作栏,而不是独立的。

我无法弄清楚如何拦截recyclerview上的触摸事件并使其缩小工具栏,然后将滚动事件返回到recyclerview。我尝试将整个事物放在一个滚动视图中,但然后recyclelerview无法正确计算它的高度并且没有显示任何内容。我尝试在recyclelerview上覆盖onscroll,发现它只会在滚动事件开始时通知我,并为我提供第一个可见的卡ID。

看起来正确的方式,但我不能为我的生活而努力,是这样的:

getSupportActionBar().setHideOnContentScrollEnabled(true);

返回:

 Caused by: java.lang.UnsupportedOperationException: Hide on content scroll is not supported in this action bar configuration.

使用传统的操作栏,在其下方放置一个工具栏,并设置hideoncontentscrollenabled也不起作用,滚动从不触发操作栏上的隐藏方法。

- 编辑 - 我能够使用传统的操作栏获取hideOnContentScrollEnabled列表视图,但行为与联系人应用程序不同。这显然不是他们使用的方法 - 它只是在listview上发生fling事件时触发操作栏上的.hide(),这与联系人应用程序明显不同,后者会拖动工具栏和滚动事件。 - / edit -

所以我放弃了那条路线,并将fill_parent放在cardview高度上,并在工具栏上设置了折叠动画。但是如何触发它以使其跟随触摸事件然后将触摸事件返回到recyclerview?

activity_main.xml中

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    >

    <android.support.v7.widget.Toolbar
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="?android:attr/actionBarSize"
        android:background="@color/colorPrimary"
        />

    <fragment android:name="me.myapplication.FragmentTab"
          android:id="@+id/tab_fragment"
          android:layout_width="match_parent"
          android:layout_height="wrap_content" />
</LinearLayout>

fragment_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical"
    android:padding="8dp"
    android:background="#eeeeee"
    >

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="fill_parent"
        />

</LinearLayout>

styles.xml

...
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
...

MainActivity.java

Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);

// Disable the logo in the actionbar, as per material guidelines
toolbar.getMenu().clear();
toolbar.setTitle("My toolbar");
setSupportActionBar(toolbar);

6 个答案:

答案 0 :(得分:17)

我还没有调查过源代码,但是这个人似乎让生活变得轻松而富有启发性。

https://github.com/ksoichiro/Android-ObservableScrollView

修改

Google刚刚发布了Android Design Library。请看一下,因为它包含了折叠工具栏的所有效果等等。

答案 1 :(得分:3)

嗯,我不知道他们是怎么做的,但是......为什么不看看源代码呢?对我们来说幸运的是,联系人应用程序在Android L上仍然是开源的(其他人不像联系人那样幸运,比如Mail,它在L上不再起作用;或键盘,自推出以来他们不再更新了他们的专有谷歌键盘)。

无论如何,这里是我认为你应该看的源代码: https://github.com/android/platform_packages_apps_contacts/blob/master/src%2Fcom%2Fandroid%2Fcontacts%2Factivities%2FActionBarAdapter.java

请注意第311行中调用update(boolean skipAnimation)的方法animateTabHeightChange(int start, int end)(第437行)。

我的猜测是那里发生的所有魔法; - )

答案 2 :(得分:2)

As of June 2015, your desired effect can be accomplished via the so called CollapsingToolbarLayout of the new design support library.

Based on the sample code here, I am figuring that:

  • the search cardview is child of the toolbar
  • the missed call cardview belongs to the collapsingtoolbar with the collapseMode attribute set to pin

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

    <android.support.design.widget.CollapsingToolbarLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:minHeight="?attr/actionBarSize"
        android:fitsSystemWindows="true"
        app:layout_scrollFlags="scroll|enterAlwaysCollapsed|enterAlways">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:fitsSystemWindows="false"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_collapseMode="pin"
            app:layout_scrollFlags="scroll|enterAlways">

            <!-- Search layout -->
            <android.support.v7.widget.CardView   
            </android.support.v7.widget.CardView>

        </android.support.v7.widget.Toolbar>

        <!-- Last call card view-->
        <android.support.v7.widget.CardView
            app:layout_collapseMode="pin">               
        </android.support.v7.widget.CardView>

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

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

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:background="@color/primary_color"
        app:layout_scrollFlags="scroll"/>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

答案 3 :(得分:2)

现在不需要第三方图书馆了! Android正式提供图书馆。您可以折叠工具栏并执行许多其他调整。

选中此android-developer's blog

不要忘记在build.gradle文件中添加此依赖项。

compile 'com.android.support:design:22.2.0'

答案 4 :(得分:1)

我发现这个图书馆似乎正在寻找您正在寻找的内容:https://github.com/kmshack/Android-ParallaxHeaderViewPager和此https://github.com/flavienlaurent/NotBoringActionBar

您可以播放视频以查看行为:https://www.youtube.com/watch?v=sCP-b0a1x5Y

它可能不是新的&#39;使用ToolBar执行此操作的标准方法,但它可以通过检查代码给您一个想法。它似乎将OnScrollListener附加到滚动内容,然后触发对条形大小的更改。

答案 5 :(得分:0)

Android's Contact app doesn't have an easy plug-and-play solution that you can grab for use in your own app.

It does a full implementation, essentially doing it the same way you would do it if you were implementing it from scratch. For context, before looking at the code, keep in mind how the views are laid out:

https://github.com/android/platform_packages_apps_contacts/blob/lollipop-release/res/layout/quickcontact_activity.xml

The MultiShrinkScroller is a FrameLayout which intermediates the scrolling behavior, but the main stuff is in a LinearLayout, so reducing the height of the higher views will "scroll" the lower views upwards.

The key file for the implementation is this one:

https://github.com/android/platform_packages_apps_contacts/blob/lollipop-release/src/com/android/contacts/widget/MultiShrinkScroller.java

public void scrollTo(int x, int y) {
    final int delta = y - getScroll();
    boolean wasFullscreen = getScrollNeededToBeFullScreen() <= 0;
    if (delta > 0) {
        scrollUp(delta);
    } else {
        scrollDown(delta);
    }
    updatePhotoTintAndDropShadow();
    updateHeaderTextSizeAndMargin();
    //... other stuff
}

private void scrollUp(int delta) {

    // Collapse higher views first
    if (getTransparentViewHeight() != 0) {
        final int originalValue = getTransparentViewHeight();
        setTransparentViewHeight(getTransparentViewHeight() - delta);
        setTransparentViewHeight(Math.max(0, getTransparentViewHeight()));
        delta -= originalValue - getTransparentViewHeight();
    }

    // Shrink toolbar as needed
    final ViewGroup.LayoutParams toolbarLayoutParams
            = mToolbar.getLayoutParams();
    if (toolbarLayoutParams.height > getFullyCompressedHeaderHeight()) {
        final int originalValue = toolbarLayoutParams.height;
        toolbarLayoutParams.height -= delta;
        toolbarLayoutParams.height = Math.max(toolbarLayoutParams.height,
                getFullyCompressedHeaderHeight());
        mToolbar.setLayoutParams(toolbarLayoutParams);
        delta -= originalValue - toolbarLayoutParams.height;
    }

    // Finally, scroll content if nothing left to shrink
    mScrollView.scrollBy(0, delta);
}

updatePhotoTintAndDropShadow(); and updateHeaderTextSizeAndMargin(); handle the change in tint and text as it gets collapsed so that it turns into the look and feel of a regular ActionBar/ToolBar.

You could grab the MultiShrinkScroller file itself and adapt it for your own use, but there are probably easier implementations nowadays (including those from Android's design library).