Могу ли я использовать onScrollListener для ScrollView?
Я использую HorizontalScrollView
в макете, и мне нужно определить, что пользователь достиг начальной и конечной точки прокрутки.
Для ListView
я попробовал onScrollListener
и можно найти начальную и конечную точку прокрутки.
Я пытался сделать то же самое в моем Scrollview
но это кажется невозможным. Есть ли другие возможные способы добиться того, что мне нужно.
Ответы
Ответ 1
Каждый экземпляр View вызывает getViewTreeObserver()
. Теперь, удерживая экземпляр ViewTreeObserver
, вы можете добавить к нему OnScrollChangedListener()
с помощью метода addOnScrollChangedListener()
.
Вы можете увидеть дополнительную информацию об этом классе здесь.
Он позволяет вам знать о каждом прокручиваемом событии, но без координат. Вы можете получить их, используя getScrollY()
или getScrollX()
изнутри слушателя.
scrollView.getViewTreeObserver().addOnScrollChangedListener(new OnScrollChangedListener() {
@Override
public void onScrollChanged() {
int scrollY = rootScrollView.getScrollY(); // For ScrollView
int scrollX = rootScrollView.getScrollX(); // For HorizontalScrollView
// DO SOMETHING WITH THE SCROLL COORDINATES
}
});
Ответ 2
Это может быть очень полезно.
Используйте NestedScrollView
вместо ScrollView
. В библиотеке поддержки 23.1 введена OnScrollChangeListener
- NestedScrollView
.
Поэтому вы можете сделать что-то вроде этого.
myScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
@Override
public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
Log.d("ScrollView","scrollX_"+scrollX+"_scrollY_"+scrollY+"_oldScrollX_"+oldScrollX+"_oldScrollY_"+oldScrollY);
//Do something
}
});
Ответ 3
Здесь выведенный HorizontalScrollView я написал для обработки уведомлений о прокрутке и прокрутке. Он правильно обрабатывает, когда пользователь остановил активную прокрутку и когда он полностью замедляется после того, как пользователь отпустит:
public class ObservableHorizontalScrollView extends HorizontalScrollView {
public interface OnScrollListener {
public void onScrollChanged(ObservableHorizontalScrollView scrollView, int x, int y, int oldX, int oldY);
public void onEndScroll(ObservableHorizontalScrollView scrollView);
}
private boolean mIsScrolling;
private boolean mIsTouching;
private Runnable mScrollingRunnable;
private OnScrollListener mOnScrollListener;
public ObservableHorizontalScrollView(Context context) {
this(context, null, 0);
}
public ObservableHorizontalScrollView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ObservableHorizontalScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
int action = ev.getAction();
if (action == MotionEvent.ACTION_MOVE) {
mIsTouching = true;
mIsScrolling = true;
} else if (action == MotionEvent.ACTION_UP) {
if (mIsTouching && !mIsScrolling) {
if (mOnScrollListener != null) {
mOnScrollListener.onEndScroll(this);
}
}
mIsTouching = false;
}
return super.onTouchEvent(ev);
}
@Override
protected void onScrollChanged(int x, int y, int oldX, int oldY) {
super.onScrollChanged(x, y, oldX, oldY);
if (Math.abs(oldX - x) > 0) {
if (mScrollingRunnable != null) {
removeCallbacks(mScrollingRunnable);
}
mScrollingRunnable = new Runnable() {
public void run() {
if (mIsScrolling && !mIsTouching) {
if (mOnScrollListener != null) {
mOnScrollListener.onEndScroll(ObservableHorizontalScrollView.this);
}
}
mIsScrolling = false;
mScrollingRunnable = null;
}
};
postDelayed(mScrollingRunnable, 200);
}
if (mOnScrollListener != null) {
mOnScrollListener.onScrollChanged(this, x, y, oldX, oldY);
}
}
public OnScrollListener getOnScrollListener() {
return mOnScrollListener;
}
public void setOnScrollListener(OnScrollListener mOnEndScrollListener) {
this.mOnScrollListener = mOnEndScrollListener;
}
}
Ответ 4
Если вы хотите узнать положение прокрутки в представлении, вы можете использовать следующую функцию расширения в классе вида:
fun View?.onScroll(callback: (x: Int, y: Int) -> Unit) {
var oldX = 0
var oldY = 0
this?.viewTreeObserver?.addOnScrollChangedListener {
if (oldX != scrollX || oldY != scrollY) {
callback(scrollX, scrollY)
oldX = scrollX
oldY = scrollY
}
}
}
Ответ 5
Вы можете использовать NestedScrollView
вместо ScrollView
. Тем не менее, при использовании Kotlin Lambda он не будет знать, что вы хотите, чтобы NestedScrollView setOnScrollChangeListener
вместо того, который был в представлении (который является уровнем API 23). Вы можете исправить это, указав первый параметр как NestedScrollView.
nestedScrollView.setOnScrollChangeListener { _: NestedScrollView, scrollX: Int, scrollY: Int, _: Int, _: Int ->
Log.d("ScrollView", "Scrolled to $scrollX, $scrollY")
}
Ответ 6
// --------Start Scroll Bar Slide--------
final HorizontalScrollView xHorizontalScrollViewHeader = (HorizontalScrollView) findViewById(R.id.HorizontalScrollViewHeader);
final HorizontalScrollView xHorizontalScrollViewData = (HorizontalScrollView) findViewById(R.id.HorizontalScrollViewData);
xHorizontalScrollViewData.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
@Override
public void onScrollChanged() {
int scrollX; int scrollY;
scrollX=xHorizontalScrollViewData.getScrollX();
scrollY=xHorizontalScrollViewData.getScrollY();
xHorizontalScrollViewHeader.scrollTo(scrollX, scrollY);
}
});
// ---------End Scroll Bar Slide---------
Ответ 7
Использовать NestedScrollView.
https://developer.android.com/reference/android/support/v4/widget/NestedScrollView.OnScrollChangeListener.html
scrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
@Override
public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
}
});
Ответ 8
вы можете определить собственный класс ScrollView и добавить интерфейс, который будет вызываться при scolling. Например:
public class ScrollChangeListenerScrollView extends HorizontalScrollView {
private MyScrollListener mMyScrollListener;
public ScrollChangeListenerScrollView(Context context) {
super(context);
}
public ScrollChangeListenerScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScrollChangeListenerScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setOnMyScrollListener(MyScrollListener myScrollListener){
this.mMyScrollListener = myScrollListener;
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if(mMyScrollListener!=null){
mMyScrollListener.onScrollChange(this,l,t,oldl,oldt);
}
}
public interface MyScrollListener {
void onScrollChange(View view,int scrollX,int scrollY,int oldScrollX, int oldScrollY);
}
}