web-dev-qa-db-fra.com

Détection lorsque AppBarLayout / CollapsingToolbarLayout est complètement développé

J'ai un fragment qui utilise le nouveau paradigme CoordinatorLayout/AppBarLayout/CollapsingToolbarLayout, et j'aimerais pouvoir détecter quand la barre d'outils de réduction est complètement développée afin que je puisse effectuer une opération sur tout le fragment dans lequel elle se trouve, par ex. extraire le fragment de la pile et en passer à un nouveau, en rejetant le fragment. J'ai le code de rejet qui fonctionne, j'ai juste besoin de savoir quand et quand ne pas l'utiliser.

J'ai un peu expérimenté avec AppBarLayout.OnOffsetChangedListener , mais je n'ai pas eu beaucoup de chance. Existe-t-il un moyen de l'utiliser pour déterminer quand les choses sont complètement développées, ou existe-t-il une méthode plus préférée que quelqu'un connaît?

Merci d'avance!

EDIT: Je vois également qu'il existe quelques implémentations pour AppBarLayout.setExpanded (...) , mais pas AppBarLayout.getExpanded () ou quelque chose de similaire, donc je suis perplexe là aussi.

18
James Pizzurro

Il ne semble pas y avoir quoi que ce soit dans les API, mais ce qui suit semble fonctionner pour moi. Cela pourrait nécessiter des tests.

boolean fullyExpanded =
    (appBarLayout.getHeight() - appBarLayout.getBottom()) == 0;

Edit: La solution ci-dessus semble fonctionner, mais comme je voulais tester cette condition lors du défilement de la barre d'applications, j'ai fini par utiliser la solution suivante avec OnOffsetChangedListener.

class Frag extends Fragment implements AppBarLayout.OnOffsetChangedListener {

    private boolean appBarIsExpanded = true;
    private AppBarLayout appBarLayout;

    @Override 
    public void onActivityCreated(Bundle state) {
        super.onActivityCreated(state);
        appBarLayout = (AppBarLayout) getActivity().findViewById(R.id.app_bar);
    }

    @Override
    public void onResume() {
        super.onResume();
        appBarLayout.addOnOffsetChangedListener(this);
    }

    @Override
    public void onStop() {
        super.onStop();
        appBarLayout.removeOnOffsetChangedListener(this);
    }

    @Override
    public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
        appBarIsExpanded = (verticalOffset == 0);
    } 

}
38
Jimeux

Ma solution est basée sur la création d'une vue personnalisée. Créez d'abord une classe étendant le AppBarLayout natif:

public class CustomAppBar extends AppBarLayout { ....

Ensuite, à l'intérieur de la classe, définissez un addOnOffsetChangedListener comme ceci:

this.addOnOffsetChangedListener...

Vous pouvez faire ce qui précède en définissant le constructeur ou peut-être en appelant une méthode à l'intérieur du constructeur. Vous avez donc besoin du constructeur, n'oubliez pas d'utiliser le constructeur avec 2 paramètres pour pouvoir l'ajouter au xml:

public CustomAppBar(Context context, AttributeSet attrs) {
        super(context, attrs);
//You can set the listener here or maybe call the method that set the listener
}

Ensuite, nous devons avoir accès à l'état de la vue, alors créez un booléen privé dans votre classe de vue personnalisée et définissez-le sur true ou false si votre vue commence à être développée ou réduite, dans ce cas, ma vue est par défaut développée:

private boolean isExpanded = true;

Vous devez maintenant mettre à jour l'état de ce booléen:

this.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
                if (verticalOffset == 0) {
                    isExpanded = true;
                } else {
                    isExpanded = false;
                }
            }
        });

L'étape suivante consiste à obtenir l'état du booléen à l'aide d'un getter à l'intérieur de la classe CustomAppBar

public boolean isExpanded() {
        return isExpanded;
    }

Ensuite, allez dans votre xml, utilisez votre vue personnalisée là-bas, puis dans l'Activité ou le Fragment obtenez la vue et utilisez la méthode pour connaître le statut AppBar

7
cutiko

Je sais que c'est peut-être un peu tard, mais en explorant le code source de l'AppBArLayout que j'ai trouvé, que le AppBarLayout.OnOffsetChangedListener traduit simplement la valeur de int getTopAndBottomOffset () = du comportement de l'AppBar.

Donc, à tout moment, vous pouvez simplement utiliser ce code pour définir si un AppBarLayout s'est développé ou non:

public boolean isAppBArExpanded(AppBarLayout abl) {
    final CoordinatorLayout.Behavior behavior = ((CoordinatorLayout.LayoutParams) abl.getLayoutParams()).getBehavior();
    return (behavior instanceof AppBarLayout.Behavior) ? (((AppBarLayout.Behavior) behavior).getTopAndBottomOffset() == 0) : false;
}
5