web-dev-qa-db-fra.com

Défilement fluide dans Android

Il existe une application sur le marché appelée images flottantes. Cette application possède l'une des logiques de défilement les plus fluides. Fondamentalement, l'application a une toile vierge couvrant tout l'écran, puis il y a des images affichées au-dessus de la toile vierge. L'utilisateur peut glisser et l'application déplace l'image dans le sens du balayage. De plus, il fait également défiler la cinétique. De plus, il n'y a pas de barres de défilement, il semble donc que le développeur ait créé une vue personnalisée implémentant toute la logique de défilement fluide.

ce serait génial si je pouvais en obtenir la source .. mais n'importe qui a un pseudo code ou une logique sur la façon d'implémenter ce type de fonctionnalité. Des pistes, des liens vers des sites seraient utiles.

32
prashant

Je n'ai aucune expérience avec OpenGL ni accéléromètre, mais glisser (appelé fling dans l'API d'Android) n'est pas difficile à réaliser. La première chose dont vous avez besoin pour créer un tel View personnalisé, c'est d'implémenter un GestureDetector et d'appeler son onTouchEvent() dans le onTouchEvent() de votre vue

GestureDetector mGD = new GestureDetector(getContext(),
                                        new SimpleOnGestureListener() {

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2,
                                float distanceX, float distanceY) {
        // beware, it can scroll to infinity
        scrollBy((int)distanceX, (int)distanceY);
        return true;
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float vX, float vY) {
        mScroller.fling(getScrollX(), getScrollY(),
                -(int)vX, -(int)vY, 0, (int)mMaxScrollX, 0, (int)mMaxScrollY);
        invalidate(); // don't remember if it's needed
        return true;
    }

    @Override
    public boolean onDown(MotionEvent e) {
        if(!mScroller.isFinished() ) { // is flinging
            mScroller.forceFinished(true); // to stop flinging on touch
        }
        return true; // else won't work
    }
});

@Override
public boolean onTouchEvent(MotionEvent event) {
    return mGD.onTouchEvent(event);
}

Alors que OnGestureListener.onScroll() appelle directement View.scrollBy(), pour la méthode onFling(), vous aurez besoin d'un Scroller.

Scroller est un objet simple qui, comme le dit la référence, encapsule le défilement. Il peut être utilisé pour un défilement continu ou pour réagir aux flings. Scroller.fling () commence une "simulation" de défilement de fling en lui-même, et en le regardant, vous pouvez copier sa fluidité avec une animation de redessin continue:

@Override
protected void onDraw(Canvas canvas) {
    // ....your drawings....

    // scrollTo invalidates, so until animation won't finish it will be called
    // (used after a Scroller.fling() )
    if(mScroller.computeScrollOffset()) {
        scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
    }
}

c'est-à-dire, jusqu'à ce que l'animation soit en cours, calculez le point atteint et faites-y défiler.

Enfin, n'oubliez pas de renvoyer true dans votre OnGestureListener.onDown(), même si vous ne voulez rien faire vers le bas, ou cela ne fonctionnera pas.

Et soyez prudent, car Scroller in Android 2.2 a un bogue pour lequel l'animation fling ne se terminera pas réellement même si elle atteint les limites que vous avez passées comme arguments (mais le décalage calculé est respecté donc il ne bougera pas vraiment).

64
bigstones

L'application Images flottantes est un projet open source. http://code.google.com/p/floatingimage/

8
rallat