当尝试从带有点击事件的视图滚动时,滚动在 NestedScrollView 中不起作用
Posted
技术标签:
【中文标题】当尝试从带有点击事件的视图滚动时,滚动在 NestedScrollView 中不起作用【英文标题】:Scroll doesn't work in NestedScrollView when try to scroll from views with click events 【发布时间】:2015-09-17 03:49:42 【问题描述】:我在布局中使用 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_
android:layout_>
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_
android:layout_
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_
android:layout_
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<!-- app:expandedTitleMarginEnd="64dp"-->
<ImageView
android:layout_
android:layout_
android:scaleType="centerCrop"
android:src="@drawable/image_load_default_big" />
<android.support.v7.widget.Toolbar
android:id="@+id/anim_toolbar"
android:layout_
android:layout_
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_
android:layout_
app:layout_scrollFlags="scroll|enterAlways"
android:fitsSystemWindows="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<RelativeLayout
android:layout_
android:layout_
android:clickable="false"
android:fitsSystemWindows="true">
<LinearLayout
android:id="@+id/changePasswordButtonContainer"
android:layout_
android:layout_
android:orientation="vertical">
<Button
android:id="@+id/changePasswordExpand"
android:layout_
android:layout_
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_
android:layout_
android:layout_below="@id/changePasswordButtonContainer"
android:layout_centerInParent="true"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:layout_
android:layout_
android:layout_gravity="center_horizontal"
android:text="Edit Your Password"
android:textColor="@color/orange" />
<EditText
android:id="@+id/etUserName"
android:layout_
android:layout_
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_
android:layout_
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_
android:layout_
android:paddingBottom="20dp"
android:paddingTop="20dp"
android:text="show password" />
<Button
android:id="@+id/btnSingIn"
android:layout_
android:layout_
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_
android:layout_
android:layout_below="@+id/changePasswordContainer"
android:orientation="vertical">
<Button
android:id="@+id/dealerToDealerExpand"
android:layout_
android:layout_
android:background="@drawable/back_img"
android:text="Dealer To Dealer Platform No"
android:textColor="@color/white"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_
android:layout_
android:layout_below="@id/dealerToDealerContainer"
android:layout_centerInParent="true"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:layout_
android:layout_
android:layout_gravity="center_horizontal"
android:text="Edit Number"
android:textColor="@color/orange" />
<EditText
android:id="@+id/dealerToDealerNo"
android:layout_
android:layout_
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_
android:layout_
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 都在消耗触摸事件。 有什么建议可以解决这个问题吗?
【问题讨论】:
你决定滚动里面有可点击的视图吗?您用fill_vertical
标记为已解决,但对我来说它只填充空白区域。它仍然不滚动可点击视图。
fill_vertical 没有解决问题,看起来问题出在 CollapsingToolbar 上,因为如果我们删除 CollapsingToolbar,它就可以正常工作了。
用22.2.1,好像解决了,能确认一下吗?
@Davidea 对我不起作用,对你有用吗?
我也有这个问题,虽然有趣的是,我在 ViewPager 中有它.. 但只有一个 Fragment 受到影响,另一个 Fragment 正确处理从可触摸开始的滚动事件......
【参考方案1】:
我遇到了同样的问题。仅当 NestedScrollView 内容高度小于设备屏幕高度时才会发生这种情况。所以解决方法是对NestedScrollView
中的视图使用setMinimumHeight(..)
方法,使其大小调整为屏幕高度:
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
它对我来说很好用。希望对你有帮助
【讨论】:
将视图的最小高度设置为 screenHeight - actionBarHeght,并没有解决我的问题。我尝试将它设置得更大一些(例如:screenHeight - actionBarHeight + 5)并且它起作用了。任何想法为什么? 这还有必要吗?这似乎是 Android / Material Design 的基础。怎么可能被忽视? 宾果游戏!奇迹般有效。但我想知道,作为 @LukeAllison 正确提到的 Material 设计中如此重要的组成部分,怎么会被忽视! 我想到了这一点并意识到不支持将滚动视图放置在滚动视图中,因为这不是一个好习惯。它使父 scrollView 无用。相反,我选择以编程方式调整视图大小以适应更新的内容,这反过来又增加了父滚动视图的高度。然而,这也并不容易,而且需要 hacky 代码!【参考方案2】:您的一个 ScrollView 会将所有事件发送到第一个在 dispatchMotionEvent 上回答为 true 的 View。
您可以避免在您的应用程序中使用此类场景或覆盖所有 dispatchMotionEvent 方法(来自滚动和视图)以不使用 ACTION_DOWN。
【讨论】:
能否请您为初学者澄清一下您的答案:)【参考方案3】:在您的 AndroidManifest.xml 中,确保将“windowSoftInputMode”属性设置为“adjustResize”。
<activity android:name=".activities.YourActivity" android:windowSoftInputMode="adjustResize">
【讨论】:
【参考方案4】:这里的解决方案(通过覆盖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_
android:layout_>
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_
android:layout_
app:layout_behavior="your.package.FixAppBarLayoutBehavior">
</android.support.design.widget.AppBarLayout>
<!-- Content -->
</android.support.design.widget.CoordinatorLayout>
这在帖子Click not working on RecyclerView in CoordinatorLayout when scrolling 中提供。
【讨论】:
以上是关于当尝试从带有点击事件的视图滚动时,滚动在 NestedScrollView 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章