无法滚动AppBarLayout并平滑地折叠工具栏和NestedScrollView

时间:2015-12-30 10:28:29

标签: android android-collapsingtoolbarlayout nestedscrollview

我正在开发一个Android应用,我在其中使用CoordinatorLayoutAppBarLayoutCollapsingToolbarLayout来使用折叠工具栏功能。

我在布局中使用NestedScrollView来展开和折叠相同布局中的AppBarLayout。当我尝试从屏幕中心向上滚动时,它不起作用,但当我尝试从屏幕右上角向上滚动屏幕时,它会顺利滚动。

下面提到的是我的xml文件

layout.xml

<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:fillViewport="true"
    android:fitsSystemWindows="true"
    android:paddingBottom="2dp"
    android:paddingLeft="5dp"
    android:paddingRight="5dp"
    android:paddingTop="5dp"
    android:layout_gravity="fill_vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/fragment_back_color"
            android:orientation="vertical">


            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:padding="5dp">

                <ImageView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:background="@drawable/new_recharge" />

                <com.spiceladdoo.views.RobotTextviewRegular
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginLeft="10dp"
                    android:text="NEW PAYMENT"
                    android:textColor="@color/offer_name_text_color" />

            </LinearLayout>


            <RelativeLayout

                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5dp"
                android:layout_marginRight="5dp"
                android:background="@color/white"
                android:paddingBottom="20dp"
                android:paddingLeft="10dp"
                android:paddingRight="10dp"
                android:paddingTop="20dp">

                <HorizontalScrollView
                    android:id="@+id/hsv"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_alignParentTop="true"
                    android:fillViewport="true"
                    android:measureAllChildren="false"
                    android:scrollbars="none">

                    <LinearLayout
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_centerInParent="true"
                        android:orientation="horizontal">

                        <LinearLayout
                            android:id="@+id/wallet_layout"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:gravity="center"
                            android:orientation="vertical">

                            <ImageView
                                android:id="@+id/wallet_recharge"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_gravity="center"
                                android:background="@drawable/wallet_recherge" />

                            <com.spiceladdoo.views.RobotTextviewRegular
                                android:layout_width="65dp"
                                android:layout_height="wrap_content"
                                android:layout_gravity="center"
                                android:layout_marginTop="5dp"
                                android:gravity="center"
                                android:text="WALLET"
                                android:textColor="@color/offer_name_text_color"
                                android:textSize="12sp" />
                            >

                        </LinearLayout>

                        <View
                            android:layout_width="5dp"
                            android:layout_height="20dp"

                            android:background="@color/white" />

                        <LinearLayout
                            android:id="@+id/prepaid_layout"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:gravity="center"
                            android:orientation="vertical">

                            <ImageView
                                android:id="@+id/prepaid_recharge"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_gravity="center"
                                android:background="@drawable/prepaid_recherge" />

                            <com.spiceladdoo.views.RobotTextviewRegular
                                android:layout_width="65dp"
                                android:layout_height="wrap_content"
                                android:layout_gravity="center"
                                android:layout_marginTop="5dp"
                                android:gravity="center"
                                android:text="PREPAID"
                                android:textColor="@color/offer_name_text_color"
                                android:textSize="12sp" />
                            >

                        </LinearLayout>

                        <View
                            android:layout_width="5dp"
                            android:layout_height="20dp"

                            android:background="@color/white" />

                        <LinearLayout
                            android:id="@+id/postpaid_layout"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:gravity="center"
                            android:orientation="vertical">

                            <ImageView
                                android:id="@+id/postpaid_recharge"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_gravity="center"
                                android:background="@drawable/postpaid_recherge" />

                            <com.spiceladdoo.views.RobotTextviewRegular
                                android:layout_width="65dp"
                                android:layout_height="wrap_content"
                                android:layout_gravity="center"
                                android:layout_marginTop="5dp"
                                android:gravity="center"
                                android:text="POSTPAID"
                                android:textColor="@color/offer_name_text_color"
                                android:textSize="12sp" />
                            >

                        </LinearLayout>

                        <View
                            android:layout_width="5dp"
                            android:layout_height="20dp"
                            android:background="@color/white" />

                        <LinearLayout
                            android:id="@+id/dth_layout"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:gravity="center"
                            android:orientation="vertical">

                            <ImageView
                                android:id="@+id/dth_recharge"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_gravity="center"
                                android:background="@drawable/dth_recherge" />

                            <com.spiceladdoo.views.RobotTextviewRegular
                                android:layout_width="65dp"
                                android:layout_height="wrap_content"
                                android:layout_gravity="center"
                                android:layout_marginTop="5dp"
                                android:gravity="center"
                                android:text="DTH"
                                android:textColor="@color/offer_name_text_color"
                                android:textSize="12sp" />
                            >

                        </LinearLayout>

                        <View
                            android:layout_width="5dp"
                            android:layout_height="20dp"
                            android:background="@color/white" />

                        <LinearLayout
                            android:id="@+id/landline_layout"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:gravity="center"
                            android:orientation="vertical">

                            <ImageView
                                android:id="@+id/landline_recharge"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_gravity="center"
                                android:background="@drawable/landline_recherge" />

                            <com.spiceladdoo.views.RobotTextviewRegular
                                android:layout_width="65dp"
                                android:layout_height="wrap_content"
                                android:layout_gravity="center"
                                android:layout_marginTop="5dp"
                                android:gravity="center"
                                android:text="LANDLINE"
                                android:textColor="@color/offer_name_text_color"
                                android:textSize="12sp" />
                            >

                        </LinearLayout>

                        <View
                            android:layout_width="5dp"
                            android:layout_height="20dp"
                            android:background="@color/white" />

                        <LinearLayout
                            android:id="@+id/datacard_layout"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:gravity="center"
                            android:orientation="vertical">

                            <ImageView
                                android:id="@+id/datacard_recharge"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_gravity="center"
                                android:background="@drawable/datacard_recherge" />

                            <com.spiceladdoo.views.RobotTextviewRegular
                                android:layout_width="65dp"
                                android:layout_height="wrap_content"
                                android:layout_gravity="center"
                                android:layout_marginTop="5dp"
                                android:gravity="center"
                                android:text="DATACARD"
                                android:textColor="@color/offer_name_text_color"
                                android:textSize="12sp" />
                            >

                        </LinearLayout>
                    </LinearLayout>
                </HorizontalScrollView>
            </RelativeLayout>


            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal"

                android:paddingBottom="10dp"
                android:paddingLeft="5dp"
                android:paddingRight="5dp"
                android:paddingTop="10dp">

                <ImageView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:background="@drawable/recent" />

                <com.spiceladdoo.views.RobotTextviewRegular
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginLeft="10dp"
                    android:text="RECENT"
                    android:textColor="@color/offer_name_text_color" />

            </LinearLayout>

            <ListView
                android:id="@+id/recent_recharge_list"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginLeft="5dp"
                android:layout_marginRight="5dp">

            </ListView>


        </LinearLayout>

        <FrameLayout xmlns:tools="http://schemas.android.com/tools"
            android:id="@+id/recharge_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="visible"
            tools:ignore="MergeRootFrame">

        </FrameLayout>
    </RelativeLayout>
</android.support.v4.widget.NestedScrollView>

当我尝试从屏幕中心向上滚动时,所需的结果是当我从移动设备的右上角向上滚动时,它应该像smmoth一样工作。

请观看下面提到的视频,以便更清楚地查看问题

https://www.dropbox.com/s/gscfc8vfc7kkpxp/device-2015-12-30-160119.mp4?dl=0

4 个答案:

答案 0 :(得分:31)

我相信,我已经钉了它:

enter image description here

您可以找到源代码 here - 随意尝试;

我以google\designlibdemo为例。

以下是Activity的样子:

<?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"
    android:id="@+id/drawer_layout"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:fitsSystemWindows="true">

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

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

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

托管ViewPagerinclude_list_viewpager.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"
    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="wrap_content"
        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|enterAlways|snap"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleMarginStart="48dp"
            app:expandedTitleMarginEnd="64dp"
            android:fitsSystemWindows="true">
            <ImageView
                android:id="@+id/image"
                android:src="@drawable/header_image"
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:scaleType="centerCrop"
                android:fitsSystemWindows="true"
                app:layout_collapseMode="parallax"/>
            <View
                android:background="#AA50AA00"
                android:layout_width="match_parent"
                android:layout_height="200dp"
                app:layout_collapseMode="parallax"/>

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

        </android.support.design.widget.CollapsingToolbarLayout>
        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:background="#50AA00"
            app:tabMode="scrollable"
            app:tabIndicatorColor="#FFF"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </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.CoordinatorLayout>

CollapsingToolbarLayout主持人Toolbarapp:layout_collapseMode="pin")以及ImageViewapp:layout_collapseMode="parallax")。

ViewPager Fragment中的托管具有以下布局:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:fillViewport="true"
    android:fitsSystemWindows="true"
    android:layout_gravity="fill_vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <LinearLayout
        android:orientation="vertical"
        android:background="#DDD"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:padding="16dp">
            <ImageView
                android:src="@drawable/mobile"
                android:layout_marginTop="2dp"
                android:layout_width="16dp"
                android:layout_height="16dp" />
            <TextView
                android:text="@string/prepaid_recharge"
                android:layout_marginStart="16dp"
                android:layout_gravity="center_vertical"
                android:textColor="#000"
                android:fontFamily="sans-serif-medium"
                android:textSize="14sp"
                android:textAllCaps="true"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
        </LinearLayout>
        ........
        <ListView
            android:id="@+id/recent_recharge_list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </LinearLayout>
</android.support.v4.widget.NestedScrollView>

所以它有这种行为app:layout_behavior="@string/appbar_scrolling_view_behavior"并填充ViewPortandroid:fillViewport="true"

实际上 - 这就是你所需要的一切。 Fragment类是非常标准的:

public class RechargeFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.recharge_fragment, container, false);
    }
}

Activity也非常标准。

同样,您可以找到我的代码示例here

NB!我发现它在模拟器上工作得很差(根本不光滑)。

我希望,这有帮助。

答案 1 :(得分:5)

android:clickable="true"的子视图中尝试NestedScrollView,如下所示:

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:clickable="true">
        </LinearLayout>
   </android.support.v4.widget.NestedScrollView>

答案 2 :(得分:3)

在使用CoordinatorLayout AppbarLayoutCollapsingToolbarLayoutNestedScrollView作为子视图时,我几乎遇到了类似的问题。

以下代码直接来自我的项目工作区。希望它有帮助!!

<?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="wrap_content"
        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="wrap_content"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">
            <ImageView
                android:id="@+id/cover_pic"
                android:layout_width="match_parent"
                android:layout_height="256dp"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax"
                android:src="@drawable/cookin"/>
            <android.support.v7.widget.Toolbar
                android:id="@+id/mToolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:layout_collapseMode="pin"/>

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


        <android.support.design.widget.TabLayout
            android:id="@+id/tabLayout"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:layout_gravity="bottom"
            android:background="?attr/colorPrimary"
            app:tabMode="scrollable"/>

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


    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

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

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_alignParentBottom="true"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <android.support.design.widget.FloatingActionButton
                android:id="@+id/fab_phone"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom|end"
                android:layout_marginRight="@dimen/fab_margin"
                android:visibility="invisible"
                app:backgroundTint="@color/colorFAB2"
                app:elevation="6dp"
                android:layout_margin="5dp"
                app:pressedTranslationZ="12dp"
                android:src="@drawable/ic_phone_white_24dp" />

            <android.support.design.widget.FloatingActionButton
                android:id="@+id/fab_book"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom|end"
                android:layout_margin="5dp"
                android:layout_marginRight="@dimen/fab_margin"
                android:visibility="invisible"
                app:elevation="6dp"
                app:backgroundTint="@color/colorFAB1"
                app:pressedTranslationZ="12dp"
                android:src="@drawable/ic_receipt_white_24dp" />
            <android.support.design.widget.FloatingActionButton
                android:id="@+id/fab_add"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom|end"
                app:elevation="6dp"
                app:backgroundTint="@color/colorAccent"
                app:pressedTranslationZ="12dp"
                android:layout_margin="@dimen/fab_margin"
                android:src="@drawable/ic_add_white_24dp" />

        </LinearLayout>

    </RelativeLayout>


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

答案 3 :(得分:3)

看起来像this的副本。虽然它指向&#34;解决了#34;线程,另一个与RecyclerView更相关。

我根据来自RecyclerView线程的Manolo GarciaKirill Boyarshinov所做的解决方案编写了我的行为。在我的情况下,在制作投掷手势时未调用onNestedFling(),因此我入侵了onNestedPreScroll()。我今天一直在使用NestedScroll在ViewPager中工作,在不同场景下的解决方案下面没有经过测试(尽管它基于我一年前为RecyclerView编写的类似代码)。

首次更新的行为(将{x}添加为app:layout_behavior="your.package.FlingBehavior">的{​​{1}}}:

android.support.design.widget.AppBarLayout

现在它应该可以平滑滚动,但NestedScrollView(和RecyclerView)的内容可以在AppBarLayout折叠之前滚动,这看起来很奇怪。要解决它follow this answer。进行小的更改以使用public final class FlingBehavior extends AppBarLayout.Behavior { private static final String TAG = FlingBehavior.class.getName(); private static final int TOP_CHILD_FLING_THRESHOLD = 1; private static final float OPTIMAL_FLING_VELOCITY = 3500; private static final float MIN_FLING_VELOCITY = 20; boolean shouldFling = false; float flingVelocityY = 0; public FlingBehavior() { } public FlingBehavior(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int velocityX, int velocityY, int[] consumed) { super.onNestedPreScroll(coordinatorLayout, child, target, velocityX, velocityY, consumed); if (velocityY > MIN_FLING_VELOCITY) { shouldFling = true; flingVelocityY = velocityY; } else { shouldFling = false; } } @Override public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout abl, View target) { super.onStopNestedScroll(coordinatorLayout, abl, target); if (shouldFling) { Log.d(TAG, "onNestedPreScroll: running nested fling, velocityY is " + flingVelocityY); onNestedFling(coordinatorLayout, abl, target, 0, flingVelocityY, true); } } @Override public boolean onNestedFling(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, float velocityX, float velocityY, boolean consumed) { if (target instanceof RecyclerView && velocityY < 0) { Log.d(TAG, "onNestedFling: target is recyclerView"); final RecyclerView recyclerView = (RecyclerView) target; final View firstChild = recyclerView.getChildAt(0); final int childAdapterPosition = recyclerView.getChildAdapterPosition(firstChild); consumed = childAdapterPosition > TOP_CHILD_FLING_THRESHOLD; } // prevent fling flickering when going up if (target instanceof NestedScrollView && velocityY > 0) { consumed = true; } if (Math.abs(velocityY) < OPTIMAL_FLING_VELOCITY) { velocityY = OPTIMAL_FLING_VELOCITY * (velocityY < 0 ? -1 : 1); } Log.d(TAG, "onNestedFling: velocityY - " + velocityY + ", consumed - " + consumed); return super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed); } } 方法而不是fullScroll(ScrollView.FOCUS_UP)否则您可能会注意到在快速滚动期间出现小闪烁,此处:

scrollTo(0, 0)

之后我称之为结束,但您可能希望继续进行以使其更加流畅地滚动,就像在Google Play中一样,有(我认为未解决的)关于它的帖子here