Search code examples
androidandroid-scrollview

Disable parent ScrollView when child ScrollView is enabled


I have two ScrollViews in my layout like so

<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>

I initially disable news_comment_section using the following code in my Activity commentSection.setOnTouchListener(new IgnoreTouch());.

IgnoreTouch is a helper class that ignores touch events like so

 private class IgnoreTouch implements View.OnTouchListener{
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return true;
    }
}

This works in disabling the scrolling for commentsList. When the Button news_comment_expand is clicked the CardView news_comment_card expands it's height to fill the screen and I call the following

newsPageScroller.setOnTouchListener(new IgnoreTouch());
newsPageScroller.requestDisallowInterceptTouchEvent(true);
commentSection.setOnTouchListener(null);

This disables news_page_scroller and enables news_comment_section. This works up until I reach the top or bottom of news_comment_section. If I continue to scroll news_comment_section after I reach the top or bottom of the list, the parent ScrollView, news_page_scroller, starts scrolling. How do I completely disable any scrolling from happening on the parent ScrollView news_page_scroller?


Solution

  • I was able to solve this by creating a class that extends ScrollView

    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);
            }
        }
    }
    

    Basically, I can call newsPageScroller.setScrollEnabled(false) to ignore all scrolling events taking place on the newsPageScroller.