启用子 ScrollView 时禁用父 ScrollView
Disable parent ScrollView when child ScrollView is enabled
我的布局中有两个 ScrollView,就像这样
<ScrollView
android:id="@+id/news_page_scroller"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Extra Content -->
<android.support.v7.widget.CardView
android:id="@+id/news_comment_card"
android:layout_width="match_parent"
android:layout_height="180dp"
app:cardCornerRadius="8sp"
app:cardElevation="@dimen/elevation_card">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/news_comment_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Comments"
android:textColor="@color/colorAccent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v7.widget.RecyclerView
android:id="@+id/news_comment_section"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/news_comment_expand"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/news_comment_header"/>
<Button
android:id="@+id/news_comment_expand"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/show_all_comments"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
</android.support.constraint.ConstraintLayout>
</ScrollView>
我最初在 Activity commentSection.setOnTouchListener(new IgnoreTouch());
中使用以下代码禁用 news_comment_section
。
IgnoreTouch
是一个助手 class,它会忽略像这样的触摸事件
private class IgnoreTouch implements View.OnTouchListener{
@Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
}
这适用于禁用 commentsList
的滚动。单击按钮 news_comment_expand
时,CardView news_comment_card
会扩展其高度以填满屏幕,我调用以下内容
newsPageScroller.setOnTouchListener(new IgnoreTouch());
newsPageScroller.requestDisallowInterceptTouchEvent(true);
commentSection.setOnTouchListener(null);
这将禁用 news_page_scroller
并启用 news_comment_section
。这一直有效,直到我到达 news_comment_section
的顶部或底部。如果我在到达列表顶部或底部后继续滚动 news_comment_section
,则父 ScrollView news_page_scroller
开始滚动。如何完全禁用父 ScrollView 上发生的任何滚动 news_page_scroller
?
我能够通过创建一个扩展 ScrollView
的 class 来解决这个问题
public class PausableScrollView extends ScrollView {
private boolean scrollEnabled = true;
public void setScrollEnabled(boolean scrollEnabled){
this.scrollEnabled = scrollEnabled;
}
public PausableScrollView(Context context) { super(context); }
public PausableScrollView(Context context, AttributeSet attrs) { super(context, attrs); }
public PausableScrollView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt){
if(scrollEnabled) {
super.onScrollChanged(l, t, oldl, oldt);
}
}
@Override
public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
if(scrollEnabled) {
super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
}
}
}
基本上,我可以调用 newsPageScroller.setScrollEnabled(false)
来忽略 newsPageScroller
上发生的所有滚动事件。
这将在滑动和滚动期间禁用从子项滚动父项,而无需手动启用和禁用:
class ContainerScrollView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0)
: ScrollView(context, attrs, defStyleAttr) {
private var isScrollingChild = false
override fun onScrollChanged(l: Int, t: Int, oldl: Int, oldt: Int) {
if (!isScrollingChild) {
super.onScrollChanged(l, t, oldl, oldt)
}
}
override fun onNestedScroll(target: View?, dxConsumed: Int, dyConsumed: Int, dxUnconsumed: Int, dyUnconsumed: Int) {
if (!isScrollingChild) {
super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed)
}
}
override fun onStartNestedScroll(child: View?, target: View?, nestedScrollAxes: Int): Boolean {
isScrollingChild = true
return super.onStartNestedScroll(child, target, nestedScrollAxes)
}
override fun onStopNestedScroll(target: View?) {
isScrollingChild = false
super.onStopNestedScroll(target)
}
}
我的布局中有两个 ScrollView,就像这样
<ScrollView
android:id="@+id/news_page_scroller"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Extra Content -->
<android.support.v7.widget.CardView
android:id="@+id/news_comment_card"
android:layout_width="match_parent"
android:layout_height="180dp"
app:cardCornerRadius="8sp"
app:cardElevation="@dimen/elevation_card">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/news_comment_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Comments"
android:textColor="@color/colorAccent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v7.widget.RecyclerView
android:id="@+id/news_comment_section"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/news_comment_expand"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/news_comment_header"/>
<Button
android:id="@+id/news_comment_expand"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/show_all_comments"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
</android.support.constraint.ConstraintLayout>
</ScrollView>
我最初在 Activity commentSection.setOnTouchListener(new IgnoreTouch());
中使用以下代码禁用 news_comment_section
。
IgnoreTouch
是一个助手 class,它会忽略像这样的触摸事件
private class IgnoreTouch implements View.OnTouchListener{
@Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
}
这适用于禁用 commentsList
的滚动。单击按钮 news_comment_expand
时,CardView news_comment_card
会扩展其高度以填满屏幕,我调用以下内容
newsPageScroller.setOnTouchListener(new IgnoreTouch());
newsPageScroller.requestDisallowInterceptTouchEvent(true);
commentSection.setOnTouchListener(null);
这将禁用 news_page_scroller
并启用 news_comment_section
。这一直有效,直到我到达 news_comment_section
的顶部或底部。如果我在到达列表顶部或底部后继续滚动 news_comment_section
,则父 ScrollView news_page_scroller
开始滚动。如何完全禁用父 ScrollView 上发生的任何滚动 news_page_scroller
?
我能够通过创建一个扩展 ScrollView
的 class 来解决这个问题public class PausableScrollView extends ScrollView {
private boolean scrollEnabled = true;
public void setScrollEnabled(boolean scrollEnabled){
this.scrollEnabled = scrollEnabled;
}
public PausableScrollView(Context context) { super(context); }
public PausableScrollView(Context context, AttributeSet attrs) { super(context, attrs); }
public PausableScrollView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt){
if(scrollEnabled) {
super.onScrollChanged(l, t, oldl, oldt);
}
}
@Override
public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
if(scrollEnabled) {
super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
}
}
}
基本上,我可以调用 newsPageScroller.setScrollEnabled(false)
来忽略 newsPageScroller
上发生的所有滚动事件。
这将在滑动和滚动期间禁用从子项滚动父项,而无需手动启用和禁用:
class ContainerScrollView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0)
: ScrollView(context, attrs, defStyleAttr) {
private var isScrollingChild = false
override fun onScrollChanged(l: Int, t: Int, oldl: Int, oldt: Int) {
if (!isScrollingChild) {
super.onScrollChanged(l, t, oldl, oldt)
}
}
override fun onNestedScroll(target: View?, dxConsumed: Int, dyConsumed: Int, dxUnconsumed: Int, dyUnconsumed: Int) {
if (!isScrollingChild) {
super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed)
}
}
override fun onStartNestedScroll(child: View?, target: View?, nestedScrollAxes: Int): Boolean {
isScrollingChild = true
return super.onStartNestedScroll(child, target, nestedScrollAxes)
}
override fun onStopNestedScroll(target: View?) {
isScrollingChild = false
super.onStopNestedScroll(target)
}
}