web-dev-qa-db-fra.com

Comment ajuster la distance de balayage vers le bas dans SwipeRefreshLayout?

J'ai implémenté SwipeRefreshLayout dans mon application. J'ai besoin de changer la hauteur qui doit être défilée pour appeler la méthode onRefresh (). Quelle méthode dois-je utiliser pour ajouter une hauteur personnalisée?

Implémentation de SwipeRefreshLayout

private SwipeRefreshLayout swipeLayout;

En création

swipeLayout   = (SwipeRefreshLayout)view.findViewById(R.id.swipe_container);
swipeLayout.setOnRefreshListener(this);
        swipeLayout.setColorScheme(Android.R.color.holo_blue_dark, 
                Android.R.color.holo_green_dark, 
                Android.R.color.holo_purple, 
                Android.R.color.holo_orange_dark);   
        swipeLayout.setSoundEffectsEnabled(true);

Implémentation d'une AsyncTask dans la méthode onrefresh

   @Override
public void onRefresh() 
{
    // Asynctask to perform some task  

}
25
Anirudh

Si vous utilisez l'API 21 de la bibliothèque de support, référez-vous à la réponse de Han He ici . Il existe une méthode pour définir la distance de déclenchement appelée setDistanceToTriggerSync.


Avant API 21, comme mentionné précédemment, il n'y a pas de méthodes publiques ou internes pour modifier la distance de déclenchement.

Cependant, si vous ne souhaitez pas conserver une copie des classes pour modifier les constantes, vous pouvez utiliser réflexion pour définir manuellement une distance de déclenchement.

swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);

// define a distance
Float mDistanceToTriggerSync = yourCalculation(); 

try {
    // Set the internal trigger distance using reflection.
    Field field = SwipeRefreshLayout.class.getDeclaredField("mDistanceToTriggerSync");
    field.setAccessible(true);
    field.setFloat(swipeLayout, mDistanceToTriggerSync);
} catch (Exception e) {
    e.printStackTrace();
}

Si vous utilisez la hauteur de la disposition pour déterminer la distance, vous souhaiterez peut-être utiliser quelque chose comme un GlobalLayoutListener.

mDistanceToTriggerSync

Dans SwipeRefreshLayout, il existe une variable interne appelée mDistanceToTriggerSync. Ceci est utilisé pour déterminer à quelle distance déclencher le rafraîchissement.

Dans le code source, il est défini par le code ci-dessous dans SwipeRefreshLayout:

final DisplayMetrics metrics = getResources().getDisplayMetrics();
mDistanceToTriggerSync = (int) Math.min(
        ((View) getParent()) .getHeight() * MAX_SWIPE_DISTANCE_FACTOR,
                REFRESH_TRIGGER_DISTANCE * metrics.density);

Ce qui précède utilise la hauteur de la vue parent et certaines constantes pour calculer la distance de déclenchement. MAX_SWIPE_DISTANCE_FACTOR (0,6) et REFRESH_TRIGGER_DISTANCE (120) sont des constantes privées de la classe que vous ne pouvez pas modifier.

Vous pouvez utiliser ce qui précède pour calculer votre distance de déclenchement et utiliser vos propres constantes pour les facteurs de distance de balayage.

GlobalLayoutListener

La définition de mDistanceToTriggerSync peut être effectuée à l'intérieur d'un écouteur de disposition globale afin que la hauteur de la disposition puisse être récupérée correctement pour calculer la distance de déclenchement. L'appel de getHeight sur une vue dans onCreate retournera toujours 0 car il n'a pas encore été dessiné. J'ai obtenu le code de ici . Vous pouvez ou non avoir besoin de le faire en fonction de vos besoins.

ViewTreeObserver vto = swipeLayout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        // Calculate the trigger distance.
        final DisplayMetrics metrics = getResources().getDisplayMetrics();
        Float mDistanceToTriggerSync = Math.min(
                ((View) swipeLayout.getParent()).getHeight() * 0.6f,
                120 * metrics.density);

        try {
            // Set the internal trigger distance using reflection.
            Field field = SwipeRefreshLayout.class.getDeclaredField("mDistanceToTriggerSync");
            field.setAccessible(true);
            field.setFloat(swipeLayout, mDistanceToTriggerSync);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // Only needs to be done once so remove listener.
        ViewTreeObserver obs = swipeLayout.getViewTreeObserver();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            obs.removeOnGlobalLayoutListener(this);
        } else {
            obs.removeGlobalOnLayoutListener(this);
        }
    }
});

Le réglage de la variable ne doit être effectué qu'une seule fois si je comprends bien le code sous-jacent, car il ne définit que mDistanceToTriggerSync s'il est égal à -1. Par conséquent, il doit être sûr de le faire une fois dans l'écouteur de disposition globale.

SwipeRefreshLayout

Si le code source de SwipeRefreshLayout vous intéresse, vous pouvez le trouver ici .

28
singularhum

La réversion 21 de la bibliothèque de support v4 a fourni une API pour définir la distance.

public void setDistanceToTriggerSync (int distance)

Vérifiez le document ici .

Encore une chose, le rév. 21 a changé le comportement de la barre de progression, c'est maintenant une image circulaire. Je n'ai aucune idée de comment retrouver l'ancien chemin.

33
Han He

Actuellement, il n'y a pas de méthode publique, ni même interne, d'ailleurs, qui peut être utilisée pour ajuster la distance de déclenchement. Mais vous pouvez copier les trois classes de la bibliothèque de support dans votre projet, puis modifier SwipeRefreshLayout à votre guise.

Voici les cours que vous devrez copier:

La distance de déclenchement est calculée à l'aide des constantes:

 private static final float MAX_SWIPE_DISTANCE_FACTOR = .6f;
 private static final int REFRESH_TRIGGER_DISTANCE = 120;

Dans votre mise en page, changez <Android.support.v4.widget.SwipeRefreshLayout.../> à <your_path_to_SwipeRefreshLayout.../> et assurez-vous de modifier vos importations, si nécessaire.

3
adneal