J'utilise une HorizontalScrollView
dans une présentation et je dois identifier l'utilisateur qui a atteint le point de départ et de fin du défilement.
Pour ListView
j'ai essayé le onScrollListener
et il est possible de trouver le point de départ et de fin du défilement.
J'ai essayé de faire la même chose dans ma Scrollview
mais cela ne semble pas possible. Existe-t-il d'autres moyens possibles de réaliser ce dont j'ai besoin?.
Merci d'avance.
Chaque instance de View appelle getViewTreeObserver()
. Maintenant, lorsque vous tenez une instance de ViewTreeObserver
, vous pouvez lui ajouter une OnScrollChangedListener()
en utilisant la méthode addOnScrollChangedListener()
.
Vous pouvez voir plus d'informations sur cette classe ici .
Il vous permet d’être au courant de chaque événement de défilement - mais sans les coordonnées. Vous pouvez les obtenir en utilisant getScrollY()
ou getScrollX()
à partir de l'écouteur.
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
}
});
Cela pourrait être très utile . Utilisez NestedScrollView
au lieu de ScrollView
. La bibliothèque de support 23.1 a introduit une variable OnScrollChangeListener
à NestedScrollView
. Vous pouvez ainsi faire quelque chose comme ceci.
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
}
});
Voici une version dérivée de HorizontalScrollView que j'ai écrite pour gérer les notifications concernant le défilement et la fin du défilement. Il gère correctement quand un utilisateur a cessé de faire défiler activement et quand il décélère complètement après avoir laissé passer l'utilisateur
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;
}
}
Si vous voulez connaître la position de défilement d'une vue, vous pouvez utiliser la fonction d'extension suivante sur la classe View:
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
}
}
}
Vous pouvez utiliser NestedScrollView
au lieu de ScrollView
. Cependant, lors de l'utilisation d'un Kotlin Lambda, il ne saura pas que vous souhaitez utiliser la variable setOnScrollChangeListener
de NestedScrollView au lieu de celle de View (niveau de l'API 23). Vous pouvez résoudre ce problème en spécifiant le premier paramètre en tant que NestedScrollView.
nestedScrollView.setOnScrollChangeListener { _: NestedScrollView, scrollX: Int, scrollY: Int, _: Int, _: Int ->
Log.d("ScrollView", "Scrolled to $scrollX, $scrollY")
}
// --------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---------
vous pouvez définir une classe ScrollView personnalisée et ajouter une interface à appeler lors du scolling.like ceci:
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);
}
}