Прокрутка не работает в NestedScrollView при попытке прокрутки из представлений с событиями щелчка

Я использую NestedScrollView в макете и пытаюсь использовать новый CoordinatorLayout из библиотеки поддержки дизайна для CollapsingToolbarLayout.

Мой файл макета выглядит так:

<?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: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="200dp"
        android:fitsSystemWindows="true"
        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"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"

            app:expandedTitleMarginStart="48dp"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">
            <!--            app:expandedTitleMarginEnd="64dp"-->
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:scaleType="centerCrop"
                android:src="@drawable/image_load_default_big" />

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

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

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

    <android.support.v4.widget.NestedScrollView
        android:id="@+id/nestedScrollVw"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_scrollFlags="scroll|enterAlways"
        android:fitsSystemWindows="true"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clickable="false"
            android:fitsSystemWindows="true">

            <LinearLayout
                android:id="@+id/changePasswordButtonContainer"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <Button
                    android:id="@+id/changePasswordExpand"
                    android:layout_width="match_parent"
                    android:layout_height="55dp"
                    android:background="@drawable/back_img"
                    android:text="Change Your Password"
                    android:textColor="@color/white"
                    android:textStyle="bold" />
            </LinearLayout>


            <LinearLayout
                android:id="@+id/changePasswordContainer"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/changePasswordButtonContainer"
                android:layout_centerInParent="true"
                android:orientation="vertical"
                android:padding="10dp">


                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_horizontal"
                    android:text="Edit Your Password"
                    android:textColor="@color/orange" />

                <EditText
                    android:id="@+id/etUserName"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="10dp"
                    android:background="@drawable/edittext_default_bg"
                    android:drawableLeft="@drawable/password_icon"
                    android:drawableRight="@drawable/tick"
                    android:hint=" Old Password"
                    android:padding="12dp"
                    android:password="true"
                    android:textColorHint="#b5b5b5" />

                <EditText
                    android:id="@+id/etPass"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="10dp"
                    android:background="@drawable/edittext_default_bg"
                    android:drawableLeft="@drawable/password_icon"
                    android:drawableRight="@drawable/cross"
                    android:hint=" New Password"
                    android:padding="12dp"
                    android:password="true"
                    android:textColorHint="#b5b5b5" />

                <RadioButton
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:paddingBottom="20dp"
                    android:paddingTop="20dp"
                    android:text="show password" />

                <Button
                    android:id="@+id/btnSingIn"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_margin="4dp"
                    android:background="@drawable/login_button_background"
                    android:paddingBottom="8dp"
                    android:paddingTop="8dp"
                    android:text="Done"
                    android:textColor="@color/white"
                    android:textStyle="bold" />
            </LinearLayout>

            <LinearLayout
                android:id="@+id/dealerToDealerContainer"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/changePasswordContainer"
                android:orientation="vertical">

                <Button
                    android:id="@+id/dealerToDealerExpand"
                    android:layout_width="match_parent"
                    android:layout_height="55dp"
                    android:background="@drawable/back_img"
                    android:text="Dealer To Dealer Platform No"
                    android:textColor="@color/white"
                    android:textStyle="bold" />
            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@id/dealerToDealerContainer"
                android:layout_centerInParent="true"
                android:orientation="vertical"
                android:padding="10dp">


                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_horizontal"
                    android:text="Edit Number"
                    android:textColor="@color/orange" />

                <EditText
                    android:id="@+id/dealerToDealerNo"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="10dp"
                    android:background="@drawable/edittext_default_bg"
                    android:drawableLeft="@drawable/password_icon"
                    android:drawableRight="@drawable/tick"
                    android:hint=" 56546789"
                    android:padding="12dp"
                    android:password="true"
                    android:textColorHint="#b5b5b5" />

                <Button
                    android:id="@+id/dealerToDealerNoDone"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_margin="4dp"
                    android:background="@drawable/login_button_background"
                    android:paddingBottom="8dp"
                    android:paddingTop="8dp"
                    android:text="Done"
                    android:textColor="@color/white"
                    android:textStyle="bold" />
            </LinearLayout>

        </RelativeLayout>
    </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>

Когда я пытаюсь прокрутить, иногда это не срабатывает. Причина этого в том, что другие элементы макета с событиями нажатия используют событие касания. В основном EditText, RadioButton, Button используют события касания. Есть предложения по решению этой проблемы?


person Arun    schedule 30.06.2015    source источник
comment
Решили ли вы прокручивать внутри интерактивные представления? Вы отметили решено с помощью fill_vertical, но для меня это всего лишь пустое место. Он по-прежнему не прокручивается с помощью интерактивных представлений.   -  person Davideas    schedule 14.07.2015
comment
fill_vertical не решило проблему, похоже, проблема связана с CollapsingToolbar, потому что, если мы удалим CollapsingToolbar, он начал работать нормально.   -  person Arun    schedule 14.07.2015
comment
С 22.2.1 вроде решено, можете подтвердить?   -  person Davideas    schedule 22.07.2015
comment
@Davidea не работает для меня, это работает для вас?   -  person Arun    schedule 24.07.2015
comment
Эта проблема решила ?? Я столкнулся с той же проблемой   -  person goldsmit409    schedule 30.07.2015
comment
У меня тоже есть эта проблема, хотя, что интересно, она у меня есть в ViewPager .. но от этого страдает только один фрагмент, другой фрагмент правильно обрабатывает события прокрутки, начиная с осязаемых ...   -  person Graeme    schedule 17.09.2015
comment
@Davidea У меня была проблема даже в 23.1.0   -  person RiA    schedule 09.07.2016
comment
Я столкнулся с теми же проблемами, что и вы, и для меня эта проблема была решена путем простого обновления библиотеки поддержки Google до 28.0.0-rc01. Надеюсь, это сработает и для вас.   -  person Fatehali Asamadi    schedule 05.09.2018


Ответы (4)


У меня такая же проблема. Это происходит только тогда, когда высота содержимого NestedScrollView меньше высоты экрана устройства. Таким образом, обходной путь - использовать метод setMinimumHeight(..) для вида внутри вашего NestedScrollView, чтобы изменить его размер до высоты экрана:

DisplayMetrics displaymetrics = new DisplayMetrics();
getBaseActivity().getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int screenHeight = displaymetrics.heightPixels;

int actionBarHeight = 0;
TypedValue tv = new TypedValue();
if (getBaseActivity().getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
    actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
}

view.setMinimumHeight(screenHeight - actionBarHeight);

где view - ваш RelativeLayout

Он отлично работает у меня. Надеюсь, это поможет тебе

person smbd uknow    schedule 01.10.2015
comment
Установка минимальной высоты представления screenHeight - actionBarHeght не решила для меня проблему. Я попытался установить его немного больше (например: screenHeight - actionBarHeight + 5), и это сработало. Есть идеи, почему? - person Sandra; 18.02.2016
comment
Это все еще необходимо? Это кажется фундаментальным для Android / Material Design. Как это можно было не заметить? - person Luke Allison; 01.06.2016
comment
бинго! Работает как шарм. Но мне интересно, как можно было упустить из виду такой важный компонент в материальном дизайне, как правильно упомянул @LukeAllison! - person sud007; 08.06.2016
comment
Я подумал об этом и понял, что размещение scrollView внутри scrollView не поддерживается, поскольку это не очень хорошая практика. Это делает родительский scrollView бесполезным. Вместо этого я решил программно изменить размер своего представления, чтобы он соответствовал содержимому по мере его обновления, что, в свою очередь, увеличило высоту родительского scrollView. Однако это тоже непросто и требует взлома кода! - person Luke Allison; 13.06.2016

Один из ваших ScrollView будет отправлять все события в первый View, который отвечает true на dispatchMotionEvent.

Вы можете избежать использования такого сценария в своем приложении ИЛИ переопределить все методы dispatchMotionEvent (из прокрутки и представлений), чтобы не использовать ACTION_DOWN.

person Marcos Vasconcelos    schedule 30.07.2015
comment
не могли бы вы пояснить свой ответ немного подробнее для новичка :) - person aya salama; 08.11.2016

Убедитесь, что в вашем AndroidManifest.xml для атрибута windowSoftInputMode установлено значение adjustResize.

<activity android:name=".activities.YourActivity"  android:windowSoftInputMode="adjustResize">
person user3546621    schedule 06.09.2016

Решение здесь (обходной путь для этой проблемы с Google путем переопределения nestedScrollview) https://gist.github.com/chrisbanes/8391b5adb9ee42180893300850ed02f2 работал как шарм!

Определите FixAppBarLayoutBehavior.java

/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package your.package;

import android.content.Context;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.View;

/**
 * Workaround AppBarLayout.Behavior for https://issuetracker.google.com/66996774
 *
 * See https://gist.github.com/chrisbanes/8391b5adb9ee42180893300850ed02f2 for
 * example usage.
 *
 * Change the package name as you wish.
 */
public class FixAppBarLayoutBehavior extends AppBarLayout.Behavior {

    public FixAppBarLayoutBehavior() {
        super();
    }

    public FixAppBarLayoutBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void onNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target,
            int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) {
        super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed,
                dxUnconsumed, dyUnconsumed, type);
        stopNestedScrollIfNeeded(dyUnconsumed, child, target, type);
    }

    @Override
    public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child,
            View target, int dx, int dy, int[] consumed, int type) {
        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);
        stopNestedScrollIfNeeded(dy, child, target, type);
    }

    private void stopNestedScrollIfNeeded(int dy, AppBarLayout child, View target, int type) {
        if (type == ViewCompat.TYPE_NON_TOUCH) {
            final int currOffset = getTopAndBottomOffset();
            if ((dy < 0 && currOffset == 0)
                    || (dy > 0 && currOffset == -child.getTotalScrollRange())) {
                ViewCompat.stopNestedScroll(target, ViewCompat.TYPE_NON_TOUCH);
            }
        }
    }
}

Использование в java:

AppBarLayout abl = findViewById(R.id.app_bar);
((CoordinatorLayout.LayoutParams) abl.getLayoutParams()).setBehavior(new FixAppBarLayoutBehavior());

Использование в xml:

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

    <android.support.design.widget.AppBarLayout
            android:id="@+id/app_bar"
            android:layout_height="..."
            android:layout_width="..."
            app:layout_behavior="your.package.FixAppBarLayoutBehavior">

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

    <!-- Content -->

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

Это предусмотрено в сообщении Нажмите не работает на RecyclerView в CoordinatorLayout, когда прокрутка.

person Surekha    schedule 15.05.2018