0

I am trying to stop my scrollview scrolling when it reaches a scrollY position. Then, change it back to scrollable when children view (recyclerview) reach the top or overscrolled.

I tried two methods

  1. onTouchListener - it doesn't interact with scrollY position
nestedScrollView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return false;
}
});
  1. setOnScrollChangeListener - don't know how to set it as non-scrollable
nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
@Override
public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
if (scrollY >400dp) {
     
}
}

Edit 1 XML

<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">

     <Linearlayout
         android:layout_width="match_parent"
         android:layout_height="match_parent">
         //include more contents card
         <androidx.recyclerview.widget.RecyclerView

            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:nestedScrollingEnabled="true"
            android:orientation="vertical"
            />
          </LinearLayout>
</androidx.core.widget.NestedScrollView>
Howard Lau
  • 163
  • 1
  • 11

1 Answers1

0

Your idea with the OnTouchListener is working but the return value which Android expects is confusing. false means scrolling is activated. true means scrolling is deactivated.

This will prevent scrolling:

scrollView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return true;
    }
});

From View.java:

/**
* Called when a touch event is dispatched to a view. This allows listeners to
* get a chance to respond before the target view.
*
* @param v The view the touch event has been dispatched to.
* @param event The MotionEvent object containing full information about
*        the event.
* @return True if the listener has consumed the event, false otherwise.
*/
boolean onTouch(View v, MotionEvent event);

Edit:

You can use both of your Listeners and "connect" them through an instance variable. Like this:

    boolean freezeScrolling = false; //This has to be an instance variable so both Listeners can access it.

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test);

        ScrollView scrollView = findViewById(R.id.scroll_view);
        Button button = findViewById(R.id.button);

        scrollView.setOnScrollChangeListener(new ScrollView.OnScrollChangeListener() {
            @Override
            public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
//                    Log.d("TAG", String.valueOf(scrollY));
                    freezeScrolling = (scrollY>100); //freeScrolling is set to true if scrollY is above 100. Otherwise to false.
            }
        });

        scrollView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return freezeScrolling; //onTouch returns the value which has been set in onScrollChange.
            }
        });

        //unfreezing test:
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                scrollView.scrollTo(0, 0); //freezeScrolling will be changed automatically.
            }
        });
einUsername
  • 1,569
  • 2
  • 15
  • 26
  • Thanks for your reply. May i know how to detect the scrollY position in order set return true or false? I want to stop it when the scroll view reach a certain position. – Howard Lau Aug 10 '20 at 01:22
  • Is it possible that I can use View v to get the ScrollY position? – Howard Lau Aug 10 '20 at 01:29