Android scrollview How to Monitor Slide Status
- 2021-11-14 07:01:40
- OfStack
ScrollView
The scrolling process of the view is actually constantly modifying the origin coordinates. When the finger touches, ScrollView will temporarily intercept the touch event and use a timer. If no finger movement event occurs after the timer reaches the point, ScrollView sends tracking events to the clicked subView; If a moving event occurs after the timer reaches the point, ScrollView cancels tracking's self-initiated scroll.
First of all, let's talk about monitoring the sliding event of NestedScrollView under 1.
If you use
nestedScrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
@Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
}
});
This method is used in API > It can only be used at 23:00. How to solve it? We can define an ScrollView ourselves
public class MyScrollView extends NestedScrollView {
private OnScrollChanged mOnScrollChanged;
public MyScrollView(Context context) {
this(context, null);
}
public MyScrollView(Context context, AttributeSet attributeSet) {
this(context, attributeSet, 0);
}
public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (mOnScrollChanged != null) {
mOnScrollChanged.onScroll(l, t, oldl, oldt);
}
}
public void setOnScrollChanged(OnScrollChanged onScrollChanged) {
this.mOnScrollChanged = onScrollChanged;
}
public interface OnScrollChanged {
void onScroll(int l, int t, int oldl, int oldt);
}
}
In this way, we can monitor sliding events by implementing onScrollChanged (), in which sliding distance can be monitored, so we can do many things well;
But now there is a requirement that "when sliding, hide a floating box on the side, and if not sliding, the floating box will be displayed", so it is necessary to monitor the sliding state. Unlike recyclerview1, scrollview can monitor sliding state.
The following is my one implementation scheme, which is implemented through CountDownTimer
Add methods to the onScrollChanged interface just now
public interface OnScrollChanged {
void onScroll(int l, int t, int oldl, int oldt);
void onTouch(boolean isDown);
}
Then override the onTouchEvent method
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (mOnScrollChanged != null) {
mOnScrollChanged.onTouch(false);
}
break;
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
if (mOnScrollChanged != null) {
mOnScrollChanged.onTouch(true);
}
break;
}
return super.onTouchEvent(ev);
}
Here, isDown=true represents a pressed or sliding state, corresponding to ACTION_DOWN and ACTION_MOVE, and fale represents ACTION_UP and ACTION_CANCEL
Use this custom scrollerview below
// Static state
private final static int SCROLL_STATE_IDLE = 1;
// Drag or inertial sliding state
private final static int SCROLL_STATE_SCROLL = 2;
// Judge whether it is a drag state
boolean isDragState = false;
int currentState = SCROLL_STATE_IDLE;
// Used here 100ms To judge whether it is already in a static state, 100ms After the end, it proves to be a static state
private CountDownTimer scrollCountTimer = new CountDownTimer(100, 1) {
@Override
public void onTick(long millisUntilFinished) {
}
@Override
public void onFinish() {
setScrollState(SCROLL_STATE_IDLE);
}
};
private void initScrollView() {
scrollView.setOnScrollChanged(new MyScrollView.OnScrollChanged() {
@Override
public void onScroll(int l, int t, int oldl, int oldt) {
if (isDragState) {// Drag status is handled separately, and scrolling status monitoring is no longer performed
return;
}
// When sliding, cancel the countdown first and set the sliding state
scrollCountTimer.cancel();
if(currentState != SCROLL_STATE_SCROLL) {
setScrollState(SCROLL_STATE_SCROLL);
}
scrollCountTimer.start();
}
@Override
public void onTouch(boolean isDown) {
isDragState = isDown;
// Here, I default the pressed state to the scrolled state, of course, you can define it separately
if (isDown) {
scrollCountTimer.cancel();
setScrollState(SCROLL_STATE_SCROLL);
} else {
scrollCountTimer.start();
}
}
});
// Finally, remember that when the page is destroyed, cancel Drop timer
Summarize