带有折叠式工具栏的Android片段标签页

3
我在我的应用程序中有一个可折叠的 `Toolbar`。我使用一个 `NavigationDrawer`,并使用不同片段之间进行切换,同时替换 `FrameLayout`,并保留了整个应用程序中的工具栏。
其中一个片段具有选项卡布局。 当我显示该片段时,它会显示在 `Toolbar` 下面,与 `Toolbar` 阴影重叠。 我希望它与 `Toolbar` 处于相同的级别,并且看起来和操作像在同一个 `AppBarLayout` 中。 此外,我想在工具栏展开时将选项卡透明化。
如何重新组织我的布局以使其正常工作?
以下是我的 Xml:
主要 Xml:
<android.support.v4.widget.DrawerLayout 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:layout_gravity="right"
    android:clickable="true"
    android:layoutDirection="rtl"
    android:fitsSystemWindows="true"
    android:id="@+id/drawer_layout">
<android.support.design.widget.CoordinatorLayout
    android:id="@+id/mainCoordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layoutDirection="rtl"
    android:background="#EEEEEE"
    android:clickable="true">
    <android.support.design.widget.AppBarLayout
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:id="@+id/toolbar_layout">
        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="250dp"
            app:collapsedTitleGravity="right"
            android:fitsSystemWindows="true"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:contentScrim="?attr/colorPrimary"
            app:collapsedTitleTextAppearance="@style/CollapsedTitleTextAppearance"
            app:expandedTitleTextAppearance="@style/ExpandedTitleTextAppearance"
            app:expandedTitleMarginEnd="64dp"
            app:expandedTitleMarginStart="48dp">
            <ImageView
                android:id="@+id/headerImage"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax"
                android:src="@drawable/soldier" />
            <View
                android:layout_width="match_parent"
                android:layout_height="88dp"
                android:background="@drawable/scrim_top"
                app:layout_collapseMode="pin" />
            <View
                android:layout_width="match_parent"
                android:layout_height="88dp"
                android:layout_gravity="bottom"
                android:layout_alignBottom="@+id/headerImage"
                android:background="@drawable/scrim_bottom" />
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:theme="@style/WhiteTitle"
                app:layout_scrollFlags="scroll|enterAlways"
                app:titleTextColor="@color/White"
                android:fitsSystemWindows="true"
                android:layout_gravity="right"
                android:layoutDirection="rtl"
                app:layout_collapseMode="pin" />
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/content_frame"
        android:animateLayoutChanges="true"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <android.support.v4.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            android:fillViewport="true" />
    </FrameLayout>
    <android.support.design.widget.FloatingActionButton
        android:id="@+id/mainFab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_gravity="bottom|end"
        android:layout_marginLeft="16dp"
        android:layout_marginBottom="16dp"
        android:layout_marginTop="5dp"
        android:elevation="8dp"
        app:pressedTranslationZ="12dp"
        app:backgroundTint="?android:colorAccent"
        android:src="@drawable/ic_perm_phone_msg_white_24px" />
    <LinearLayout
        android:id="@+id/miniFabFrame"
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="invisible"
        android:layout_alignParentLeft="true"
        android:layout_gravity="bottom|end"
        android:layout_marginLeft="20dp"
        android:layout_marginBottom="80dp"
        android:padding="0dp">
        <android.support.design.widget.FloatingActionButton
            android:id="@+id/messageFab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true"
            android:elevation="8dp"
            android:layout_marginTop="5dp"
            android:layout_marginRight="0dp"
            android:layout_marginBottom="5dp"
            android:layout_marginLeft="5dp"
            app:pressedTranslationZ="12dp"
            app:backgroundTint="?android:colorPrimary"
            app:fabSize="mini"
            android:src="@drawable/ic_textSMS_white_24px" />
        <android.support.design.widget.FloatingActionButton
            android:id="@+id/callFab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true"
            android:layout_marginTop="5dp"
            android:layout_marginRight="0dp"
            android:layout_marginBottom="5dp"
            android:layout_marginLeft="5dp"
            android:elevation="8dp"
            app:pressedTranslationZ="12dp"
            app:backgroundTint="?android:colorPrimary"
            app:fabSize="mini"
            android:src="@drawable/ic_call_white_24px" />
    </LinearLayout>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="right"
    android:id="@+id/nav_view"
    android:layoutDirection="rtl"
    app:headerLayout="@layout/header"
    app:menu="@menu/nav_menu" />

使用选项卡布局的碎片:

<LinearLayout 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:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:fitsSystemWindows="true"
    android:id="@+id/halachot_layout"
    android:layoutDirection="ltr"
    android:animateLayoutChanges="true">
  <android.support.design.widget.AppBarLayout
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:elevation="0dp"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
    <com.refractored.PagerSlidingTabStrip
        android:id="@+id/halachotTabs"
        android:layout_below="@id/halachot_layout"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@android:color/transparent"
        android:fitsSystemWindows="true"
        pstsPaddingMiddle="false"
        app:pstsShouldExpand="true" />
    </android.support.design.widget.AppBarLayout>
    <android.support.v4.view.ViewPager
       android:id="@+id/halachotPager"
       android:layout_width="match_parent"
       android:layout_height="0dp"
       android:layout_weight="1" />
</LinearLayout>

任何指导都将不胜感激。
谢谢。

谢谢你的答复,但我更愿意用不同的方式来完成它。请看下面我的回答。 - amitairos
5个回答

3
您应该按照以下结构进行设置:

<?xml version="1.0" encoding="utf-8"?>

<android.support.design.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

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

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

            <android.support.design.widget.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:layout_gravity="bottom"
                app:tabMode="scrollable"
                app:tabContentStart="72dp" />

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:layout_collapseMode="parallax" />

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

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

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

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="8dp"
        android:src="@drawable/ic_done"
        app:layout_anchor="@id/tabs"
        app:layout_anchorGravity="center|left|start"
        app:fabSize="mini"
        app:layout_behavior="com.support.android.designlibdemo.ScrollAwareFABBehavior"
        app:borderWidth="0dp" />

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

这里摘自此处

另请参见答案,它在那里解释得很好。

如果您需要进一步的解释,请阅读以下博客:

http://blog.grafixartist.com/parallax-scrolling-tabs-design-support-library

http://blog.nkdroidsolutions.com/collapsing-toolbar-with-tabs-android-example

https://lab.getbase.com/nested-scrolling-with-coordinatorlayout-on-android/


谢谢,但它对我的情况并没有真正的帮助,因为我的选项卡布局仅位于一个片段中。如果我把它放在主xml中,它会出现在所有片段中,这不是我想要的。 - amitairos
你知道如何在我的布局中做这个吗? - amitairos
1
不是,但我一定会去看看。 - TapanHP
有什么想法吗?赏金将在3天后结束... :-) - amitairos
1
非常抱歉,已经尝试了很多次但仍然没有找到完美的解决方案。不过,在我的搜索中我找到了一篇关于选项卡和片段布局相关情况的好博客,并提供了图片,你可以阅读一下,或许会有所帮助。https://inthecheesefactory.com/blog/android-design-support-library-codelab/en - TapanHP
好的,我会查看。谢谢。 - amitairos

3
当我展示该片段时,它会显示在工具栏下方,工具栏的阴影会重叠在上面。我希望它与工具栏处于同一级别,并且看起来和行为像是在同一个AppBarLayout中。
为此,请按照材料设计指南在此描述给选项卡布局提供相同的高程,默认高程为4 dp。因此,请尝试给选项卡布局提供高程。
此外,当工具栏展开时,我想使选项卡透明。
为此,请添加如下类:
public abstract class AppBarStateChangeListener implements AppBarLayout.OnOffsetChangedListener {

public enum State {
    EXPANDED,
    COLLAPSED,
    IDLE
}

private State mCurrentState = State.IDLE;

@Override
public final void onOffsetChanged(AppBarLayout appBarLayout, int i) {
    if (i == 0) {
        if (mCurrentState != State.EXPANDED) {
            onStateChanged(appBarLayout, State.EXPANDED);
        }
        mCurrentState = State.EXPANDED;
    } else if (Math.abs(i) >= appBarLayout.getTotalScrollRange()) {
        if (mCurrentState != State.COLLAPSED) {
            onStateChanged(appBarLayout, State.COLLAPSED);
        }
        mCurrentState = State.COLLAPSED;
    } else {
        if (mCurrentState != State.IDLE) {
            onStateChanged(appBarLayout, State.IDLE);
        }
        mCurrentState = State.IDLE;
    }
}

public abstract void onStateChanged(AppBarLayout appBarLayout, State state);
 }

然后在您的活动中像这样使用它

appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() {
@Override
public void onStateChanged(AppBarLayout appBarLayout, State state) {
    Log.d("STATE", state.name());

    //if state is expanded then set your tab layout background to transparent
  }
});

3

我遇到了类似的问题。 我解决了这个问题,通过在显示具有不需要的阴影的片段时,移除ActionBar的elevation

我在Activity中添加了以下两个方法:

public void setToolbarElevation(){
        if (Build.VERSION.SDK_INT >= 21){
            if (toolbar!=null) {
                toolbar.setElevation(getResources().getDimensionPixelSize(R.dimen.actionbar_elevation));
            }
        }
    }

public void removeToolbarElevation(){
        if (Build.VERSION.SDK_INT >= 21){
            if (toolbar!=null) {
                toolbar.setElevation(0);
            }
        }
    }

当您调用带有选项卡的片段时,在活动中调用removeToolbarElevation(),阴影应该消失。

如果可以,请告诉我它是否有效。


谢谢你的回答,但我更喜欢用更简洁的方式来完成它。请看下面我的回答。谢谢! - amitairos

2
感谢大家的意见。 我最终做的是这样的:
主要的 XML:
<android.support.v4.widget.DrawerLayout 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:layout_gravity="right"
android:clickable="true"
android:layoutDirection="rtl"
android:fitsSystemWindows="true"
android:id="@+id/drawer_layout">
<android.support.design.widget.CoordinatorLayout
    android:id="@+id/mainCoordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layoutDirection="rtl"
    android:background="#EEEEEE"
    android:clickable="true">
    <android.support.design.widget.AppBarLayout
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:id="@+id/toolbar_layout">
        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="256dp"
            android:fitsSystemWindows="true"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:contentScrim="?attr/colorPrimary"
            app:collapsedTitleGravity="right"
            app:expandedTitleGravity="bottom|right"
            app:expandedTitleMarginBottom="50dp"
            app:collapsedTitleTextAppearance="@style/CollapsedTitleTextAppearance"
            app:expandedTitleTextAppearance="@style/ExpandedTitleTextAppearance"
            app:expandedTitleMarginEnd="64dp"
            app:expandedTitleMarginStart="48dp">

            <ImageView
                android:id="@+id/headerImage"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax"
                android:background="@drawable/soldier" />
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:gravity="top"
                app:titleTextColor="@color/White"
                android:fitsSystemWindows="true"
                android:layout_gravity="right"
                android:layoutDirection="rtl"
                app:layout_collapseMode="pin"
                android:minHeight="?attr/actionBarSize"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:titleMarginTop="15dp" />
        </android.support.design.widget.CollapsingToolbarLayout>
        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:layout_gravity="bottom"
            app:tabIndicatorHeight="3dp"
            android:layoutDirection="ltr"
            app:tabIndicatorColor="@android:color/white"
            app:tabSelectedTextColor="@color/White"
            app:tabTextColor="@color/Black"
            app:tabMode="fixed"
            app:tabGravity="fill" />
    </android.support.design.widget.AppBarLayout>
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/content_frame"
        android:animateLayoutChanges="true"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <android.support.v4.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            android:fillViewport="true" />
    </FrameLayout>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="right"
    android:id="@+id/nav_view"
    android:layoutDirection="rtl"
    app:headerLayout="@layout/header"
    app:menu="@menu/nav_menu" />
</android.support.v4.widget.DrawerLayout>

然后,当我切换片段时,我只在我想要它们出现的片段中显示选项卡,并在不想要它们显示时隐藏它们:

toolbar_layout.SetExpanded(true);
tabs.Visibility = ViewStates.Gone;

当我想向他们展示:

toolbar_layout.SetExpanded(false,false);
tabs.Visibility = ViewStates.Visible;

尽管我无法使它们透明,但我决定在显示它们时仅折叠工具栏,并禁用带有选项卡的片段上的扩展。
也许不是最好的解决方案,但对我来说效果非常好。
这些链接真的对我很有帮助:
- http://blog.iamsuleiman.com/parallax-scrolling-tabs-design-support-library/
- http://blog.iamsuleiman.com/material-design-tabs-with-android-design-support-library/
- 如何在CollapsingToolbarLayout中使用TabLayout和Toolbar?
- http://manishkpr.webheavens.com/android-material-design-tabs-collapsible-example/
- 如何在带有选项卡的片段(还包含一个recyclerview)中禁用工具栏的扩展
在此处查看其外观: https://youtu.be/y2xLVSQ_NGM 这可能不是最好的解决方案,但我想要一个看起来更好、更清晰的方式。
感谢大家的帮助!

2
你需要阅读这篇文章:博客。这篇文章结合了你所需的内容,即 DrawerLayout + Fragments + CollapsingToolbarLayout 的组合。 activity_main.xml
<?xml version="1.0" encoding="utf-8"?>

<android.support.v4.widget.DrawerLayout 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:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <include
        layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

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

app_bar_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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"
    tools:context=".MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="192dp"
        android:theme="@style/AppTheme.AppBarOverlay">

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

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:layout_collapseMode="pin"
                app:layout_scrollFlags="scroll|enterAlways"
                app:popupTheme="@style/AppTheme.PopupOverlay" />
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        android:src="@android:drawable/ic_dialog_email" />

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

content_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView 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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".MainActivity"
    tools:showIn="@layout/app_bar_main">

    <FrameLayout
        android:id="@+id/content_main_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</android.support.v4.widget.NestedScrollView>

输出:

在这里输入图片描述


@amitairos 你有检查过我的答案吗? - Harshad Pansuriya
谢谢你的回答,但是那并没有展示如何在只有一个片段中使用选项卡。不过还是谢谢! - amitairos
请看下面我的答案。 - amitairos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接