Android scrollview onScrollChanged
j'ai un contenu fixe dans ma vue texte à l'intérieur d'une vue parchemin. Lorsque l'utilisateur passe à une certaine position, je voudrais démarrer une activité ou déclencher un 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 trouver la position de la vue de défilement.
j'ai trouvé cette réponse, est-il une solution plus facile à cela plutôt que de déclarer une interface, over ride le scrollview etc comme vu sur le lien que j'ai posté?
10 réponses
Pas de.
ScrollView ne fournit pas d'écouteur pour les événements de défilement ou même un moyen de vérifier jusqu'où l'Utilisateur a défiler, donc vous devez faire ce qui est suggéré par le lien.
il y a un moyen beaucoup plus facile que de sous-classer le ScrollView
. L'objet ViewTreeObserver
du ScrollView
peut être utilisé pour écouter les rouleaux.
étant donné que l'objet ViewTreeObserver
pourrait changer pendant la durée de vie du ScrollView
, nous devons enregistrer un OnTouchListener
sur le ScrollView
pour obtenir le ViewTreeObserver
au moment du rouleau.
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):
commençant par API 23 , le View
D'Android a un OnScrollChangeListener
et le setter correspondant .
le NestedScrollView de la bibliothèque de soutien prend également en charge la définition d'un écouteur de parchemin avant même le niveau de L'API. Pour autant que je sache, NestedScrollView
peut être utilisé en remplacement de la normal ScrollView
sans aucun problème.
en fait, il y a un moyen de savoir jusqu'à quel point l'Utilisateur a roulé. La méthode getScrollY () de ScrollView vous le dit.
j'ai prolongé mon scrollView. ce lien peut vous 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 exactement comme android.widget.ScrollView, mais il prend en charge agir à la fois un parent de défilement imbriqué et l'enfant sur les deux nouvelles et anciennes versions D'Android.
1ère Utilisation NestedScrollView plutôt la liaison ScrollView
2e Set de Défilement à l'écoute, comme ça, pour détecter le déplacement de l'axe Y pour un headerView 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);
}
}
});
il est composant prêt à l'emploi , qui aide à écouter les événements de défilement de vues arbitraires sur Android. En interne, ce composant ajoute L'auditeur de scroll events de ViewTreeObserver sur les appareils avec L'ancienne API Android (similaire à celle proposée dans la réponse de Shubhadeep Chaudhuri) et L'auditeur de scroll events de View scroll sur les appareils avec la nouvelle API Android (niveau API 23+).
il suffit d'utiliser NestedScroll
et NestedScroll.setOnScrollChangeListener()
.
à partir de 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
}
});
vous pouvez utiliser ce déclencheur pour montrer Toast ou démarrer L'activité
scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
@Override
public void onScrollChanged() {
// do something when Scroll
}
});