J'ai un contenu fixe dans ma vue de texte à l'intérieur d'une vue de défilement. Lorsque l'utilisateur fait défiler jusqu'à une certaine position, j'aimerais commencer une activité ou déclencher une Toast
.
<ScrollView xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent" Android:layout_height="fill_parent"
Android:id="@+id/scroller">
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:orientation="vertical" Android:layout_width="fill_parent"
Android:layout_height="fill_parent">
<TextView Android:layout_width="fill_parent" Android:id="@+id/story"
Android:layout_height="wrap_content" Android:text="@string/lorem"
Android:gravity="fill" />
</LinearLayout>
</ScrollView>
Mon problème est de mettre en œuvre la méthode protégée onScrollChanged
pour connaître la position de la vue de défilement.
J'ai trouvé ceci réponse, y a-t-il une solution plus facile à cela plutôt que de déclarer une interface, de passer outre le scrollview, etc. comme on le voit sur le lien que j'ai posté?
Non.
ScrollView ne fournit pas d'écouteur pour les événements de défilement ni même un moyen de vérifier jusqu'à quel point l'utilisateur a fait défiler l'écran. Vous devez donc suivre les indications du lien.
Il existe un moyen beaucoup plus facile que de sous-classer la ScrollView
. L'objet ViewTreeObserver
de la ScrollView
peut être utilisé pour écouter les parchemins.
Puisque l'objet ViewTreeObserver
peut changer pendant la durée de vie de la ScrollView
, nous devons enregistrer une OnTouchListener
sur la ScrollView
pour qu'elle soit ViewTreeObserver
au moment du défilement.
final ViewTreeObserver.OnScrollChangedListener onScrollChangedListener = new
ViewTreeObserver.OnScrollChangedListener() {
@Override
public void onScrollChanged() {
//do stuff here
}
};
final ScrollView scrollView = (ScrollView) findViewById(R.id.scroller);
scrollView.setOnTouchListener(new View.OnTouchListener() {
private ViewTreeObserver observer;
@Override
public boolean onTouch(View v, MotionEvent event) {
if (observer == null) {
observer = scrollView.getViewTreeObserver();
observer.addOnScrollChangedListener(onScrollChangedListener);
}
else if (!observer.isAlive()) {
observer.removeOnScrollChangedListener(onScrollChangedListener);
observer = scrollView.getViewTreeObserver();
observer.addOnScrollChangedListener(onScrollChangedListener);
}
return false;
}
});
Cette question est assez ancienne, mais au cas où quelqu'un passerait (comme moi):
À partir de API 23, la variable View
d'Android a une variable OnScrollChangeListener
et le paramètre de configuration correspondant .
Le NestedScrollView de la bibliothèque Support prend également en charge la définition d'un écouteur de défilement avant même le niveau de l'API. Autant que je sache, NestedScrollView
peut être utilisé en remplacement de la ScrollView
normale sans aucun problème.
En réalité, il existe un moyen de savoir dans quelle mesure l'utilisateur a fait défiler l'écran. La méthode getScrollY () de ScrollView vous le dit.
J'ai étendu mon scrollView. Ce lien peut aider.
class MyScroll extends ScrollView {
boolean onTop=true;
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
//Log.d(TAG, "scroll changed: " + this.getTop() + " "+t);
if(t <= 0){
onTop = true;
//Log.d(TAG, "scroll top: " + t);
super.onScrollChanged(l, t, oldl, oldt);
return;
// reaches the top end
}
onTop = false;
View view = (View) getChildAt(getChildCount()-1);
int diff = (view.getBottom()-(getHeight()+getScrollY()+view.getTop()));// Calculate the scrolldiff
if( diff <= 0 ){
// if diff is zero, then the bottom has been reached
}
super.onScrollChanged(l, t, oldl, oldt);
}
}
NestedScrollView est semblable à Android.widget.ScrollView, mais il prend en charge le rôle de parent et d'enfant de défilement imbriqué sur les versions nouvelles et anciennes d'Android.
1er - Utilisez la liaison NestedScrollView à la place de ScrollView
2ème - Définissez le programme d'écoute de défilement, comme celui-ci, pour détecter l'axe Y se déplaçant pour un en-têteVue par exemple
nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
@Override
public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
Log.d(TAG, "onScrollChangeForY - scrollY: " + scrollY + " oldScrollY: " + oldScrollY);
int MOVE = -1, SCROLL_UP = 0, SCROLL_DOWN = 1;
float initialPositionY = headerView.getY();
MOVE = scrollY > oldScrollY ? SCROLL_UP : SCROLL_DOWN;
if (MOVE == SCROLL_UP) {
int incrementY = scrollY - oldScrollY;
headerView.setY(initialPositionY - incrementY);
} else {
int incrementY = oldScrollY - scrollY;
headerView.setY(initialPositionY + incrementY);
}
}
});
vous pouvez utiliser ce déclencheur pour afficher Toast ou Démarrer l'activité
scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
@Override
public void onScrollChanged() {
// do something when Scroll
}
});
Il suffit d'utiliser NestedScroll
et NestedScroll.setOnScrollChangeListener()
.
Il existe un composant prêt à l'emploi , qui permet d'écouter les événements de défilement de vues arbitraires sous Android. En interne, ce composant ajoute l'écouteur d'événements de défilement ViewTreeObserver sur les appareils dotés d'une ancienne API Android (similaire à celle proposée dans la réponse de Shubhadeep Chaudhuri) et l'écouteur Afficher les événements de défilement sur les appareils dotés d'une nouvelle API Android (API de niveau 23+).
À partir de l'API 23 Android M, vous pouvez utiliser OnScrollChangeListener.
scrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
@Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
//work with parameters
}
});