API 19 Scrollview no momentum

2019-04-13 00:13发布

问题:

I have a NestedScrollView within a CoordinatorLayout and it contains a recyclerView. The whole fragment, which is very long, has no scroll momentum and I'm not sure what I can do to fix it. I previously had this problem with higher Android versions and was able to include

android:nestedScrollingEnabled="false"

to solve my problem. However, that was added in api 21 and my project supports 19+. My app still has no momentum on this fragment for api 19 devices.

Below is my xml:

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:background="@color/primary_color"
    android:fitsSystemWindows="true">

<android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="android.support.design.widget.AppBarLayout$ScrollingViewBehavior">

    <android.support.percent.PercentRelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:nestedScrollingEnabled="false">

        <ImageView
                android:id="@+id/logo"
                android:src="@drawable/logo"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="@dimen/profile_margin_medium_huge"
                android:layout_marginBottom="46dp"
                android:layout_marginRight="@dimen/activity_horizontal_margin"
                android:layout_marginLeft="@dimen/activity_horizontal_margin"
                android:layout_alignParentEnd="true"/>

        <TypefaceTextView
                android:id="@+id/textview_title"
                android:layout_below="@id/logo"
                android:text="@string/title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                style="@style/myStyle"
                android:layout_marginLeft="@dimen/activity_horizontal_margin"
                android:layout_marginRight="@dimen/activity_horizontal_margin"
                android:layout_marginBottom="16dp"
                android:layout_alignParentLeft="true"/>

        <TypefaceTextView
                android:id="@+id/textview_byline"
                android:text="@string/byline"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                style="@style/myStyle"
                android:layout_below="@id/textview_title"
                android:layout_marginLeft="@dimen/activity_horizontal_margin"
                android:layout_marginRight="@dimen/activity_horizontal_margin"
                android:layout_marginBottom="40dp"/>

        <RadioGroup
                android:id="@+id/radiogroup_filter"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:layout_below="@id/textview_byline"
                android:layout_alignParentRight="true"
                android:layout_marginLeft="@dimen/activity_horizontal_margin"
                android:layout_marginRight="@dimen/activity_horizontal_margin"
                android:layout_marginBottom="@dimen/activity_vertical_margin">

            <TypefaceRadioButton
                    android:id="@+id/button_filter_new"
                    android:text="@string/filter_new"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    style="@style/buttonStyleRadio"
                    android:theme="@style/ButtonSecondary"
                    android:button="@null"/>

            <TypefaceRadioButton
                    android:id="@+id/button_filter_history"
                    android:text="@string/filter_history"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    style="@style/ButtonStyleRadio"
                    android:theme="@style/ButtonSecondary"
                    android:layout_alignParentRight="true"
                    android:button="@null"/>

        </RadioGroup>
        <android.support.v7.widget.RecyclerView
                android:id="@+id/recyclerview"
                android:nestedScrollingEnabled="false"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/radiogroup_filter"
                android:layout_marginLeft="@dimen/activity_horizontal_margin"
                android:layout_marginRight="@dimen/activity_horizontal_margin"
                android:layout_marginBottom="50dp"/>
        <android.support.percent.PercentRelativeLayout
                android:id="@+id/container_links"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/recyclerview"
                android:visibility="gone">
            <ImageView
                    android:id="@+id/image_link_1"
                    app:layout_widthPercent="100%"
                    app:layout_aspectRatio="158%"
                    android:scaleType="centerCrop"
                    android:layout_alignParentTop="true"/>
            <TypefaceTextView
                    android:id="@+id/text_link_1"
                    android:text="@string/text_1"
                    app:layout_widthPercent="100%"
                    app:layout_aspectRatio="158%"
                    android:gravity="bottom|left"
                    android:paddingLeft="@dimen/activity_horizontal_margin"
                    android:paddingRight="@dimen/activity_horizontal_margin"
                    android:paddingTop="32dp"
                    android:paddingBottom="32dp"
                    style="@style/myStyle"
                    android:layout_alignParentTop="true"/>
            <ImageView
                    android:id="@+id/image_link_2"
                    app:layout_widthPercent="100%"
                    app:layout_aspectRatio="158%"
                    android:scaleType="centerCrop"
                    android:layout_below="@id/image_link_1"/>
            <TypefaceTextView
                    android:id="@+id/text_link_2"
                    android:text="@string/text_2"
                    app:layout_widthPercent="100%"
                    app:layout_aspectRatio="158%"
                    android:gravity="bottom|right"
                    android:paddingLeft="@dimen/activity_horizontal_margin"
                    android:paddingRight="@dimen/activity_horizontal_margin"
                    android:paddingTop="32dp"
                    android:paddingBottom="32dp"
                    android:layout_below="@id/image_link_1"
                    style="@style/myStyle"/>
        </android.support.percent.PercentRelativeLayout>
    </android.support.percent.PercentRelativeLayout>
</android.support.v4.widget.NestedScrollView>

回答1:

I was able to recreate your symptoms in my test project. I fixed it be adding the following code in onCreate() for the activity:

final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
recyclerView.setOnFlingListener(new RecyclerView.OnFlingListener() {
        @Override
        public boolean onFling(int velocityX, int velocityY) {
            recyclerView.dispatchNestedFling(velocityX, velocityY, false);
            return false;
        }
    });

I added a fling listener to the RecyclerView, and in onFling(), I call dispatchNestedFling() to let the parent know that a fling is occurring. The parent can then consume the fling or observe the child fling.

https://developer.android.com/reference/android/support/v4/view/NestedScrollingChild.html#dispatchNestedFling(float, float, boolean)

dispatchNestedFling

added in version 22.1.0 boolean dispatchNestedFling (float velocityX, float velocityY, boolean consumed) Dispatch a fling to a nested scrolling parent.

This method should be used to indicate that a nested scrolling child has detected suitable conditions for a fling. Generally this means that a touch scroll has ended with a velocity in the direction of scrolling that meets or exceeds the minimum fling velocity along a scrollable axis.

If a nested scrolling child view would normally fling but it is at the edge of its own content, it can use this method to delegate the fling to its nested scrolling parent instead. The parent may optionally consume the fling or observe a child fling.

This is working on my emulator running API 19. Obviously, YMMV.



回答2:

There is a simpler way:

Java

recyclerView.setNestedScrollingEnabled(false);

Kotlin

recyclerView.isNestedScrollingEnabled = false