27 votes

Animer le changement de disposition de la feuille inférieure

Dans mon application, j'utilise une feuille inférieure (à partir de la bibliothèque de prise en charge) qui fonctionne très bien. Maintenant, j'aimerais animer un changement de présentation alors que la feuille est déplacée vers le haut. Pour cela, j'ai créé une sous-classe de BottomSheetCallback (ce qui est normalement un à l'intérieur de la classe d'un Fragment donc pas tous les objets utilisés dans ce calss sont initialisés ici):

public class MyBehavior extends BottomSheetBehavior.BottomSheetCallback {

    Transition transition;
    float lastOffset = 0;
    Scene scene;

    public PlayerBehavior() {
        TransitionInflater inflater = TransitionInflater.from(getContext());
        transition = inflater.inflateTransition(R.transition.player);
        //transition.setDuration(300);

        scene = fullLayout;

        transition.setInterpolator(new Interpolator() {
            @Override
            public float getInterpolation(float v) {
                return lastOffset;
            }
        });
    }

    @Override
    public void onStateChanged(@NonNull View bottomSheet, int newState) {
        if(newState == BottomSheetBehavior.STATE_DRAGGING) {
            TransitionManager.go(scene, transition);
        }
    }

    @Override
    public void onSlide(View bottomSheet, final float slideOffset) {
        scene = (slideOffset > lastOffset) ? smallLayout : fullLayout;
        lastOffset = slideOffset;
    }
}

Comme vous pouvez le voir j'ai aussi créé deux Scene à partir de différents fichiers de mise en page et une coutume Transition pour animer entre les scènes avec l' TransitionManager. Mon problème est que l' Transition devrait être fondée sur l' slideOffset paramètre (dans la gamme de 0 à 1), mais l' TransitionManager utilise l' Animation de la classe dans le fond, qui est normalement basée sur le temps de en Android.

J'ai essayé de créer le custom Intapolator mais cela ne fonctionne pas correctement. Alors, comment puis-je créer un Transition qui est basé sur une variable externe et non pas sur le temps?

1voto

Prashant Kumar Points 21

En fonction de votre description, je pense que vous essayez d'atteindre quelque chose comme google maps en bas de la feuille de comportement. Les modifications de mise en page comme le bottomsheet est déplacée vers le haut.

Si c'est ce que vous essayez d'atteindre, alors vous n'avez pas besoin de mettre en place des animations personnalisées, comme le bottomsheetdialog lui-même a ceux des comportements de l'animation lorsqu'il est incorporé à l'intérieur d'un parent, Coordonnateur de la Mise en page.

Voici un code d'exemple de la façon dont je suis en œuvre le même comportement. Il fait également le FloatingActionButton invisible lorsque le bottomsheet est traîné jusqu'à la pleine taille de l'écran :

  1. Créer un bottomsheetdialog que vous souhaitez utiliser à l'intérieur de votre page principale

    public class CustomBottomDialog extends BottomSheetDialogFragment {
    
    String mSomeName;
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // if some arguments are passed from the calling activity 
        mSomeName = getArguments().getString("some_name");
    
    
    }
    
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View bottomSheet = inflater.inflate(R.layout.bottomsheet_layout, container, false);
         // initialise your bottomsheet_layout items here 
        TextView tvName = bottomSheet.findViewById(R.id.display_name);
        tvName.setText(mSomeName); 
        tvName.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
               // do something here
                ((MainActivity)getActivity()).doSomething();
            }
        });
    
        return bottomSheet;
    }
    }
    
  2. bottomsheet_layout:

    <android.support.design.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <android.support.design.widget.FloatingActionButton
    android:id="@+id/nav"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/navigation_tilt_grey"
    app:backgroundTint="@color/colorAccent"
    app:elevation="3dp"
    app:fabSize="normal"
    android:layout_marginEnd="@dimen/activity_horizontal_margin"
    app:layout_anchor="@+id/live_dash"
    app:layout_anchorGravity="top|right" />
    
    <!--BottomSheet-->
    
    <android.support.v4.widget.NestedScrollView
    android:id="@+id/live_dash"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#F3F3F3"
    android:clipToPadding="true"
    app:layout_behavior="android.support.design.widget.BottomSheetBe 
    havior"
    tools:layout_editor_absoluteY="150dp">
    
    <!--Include your items here, the height of all items combined
    will take the main screen layout size with animation-->
    
    </android.support.v4.widget.NestedScrollView>
    
    </android.support.design.widget.CoordinatorLayout>
    
  3. L'appel de cette BottomSheet de votre activité:

    public void notifyBottomSheet(String somename){
    
    BottomSheetDialogFragment customDialogFragment = new CustomBottomDialog();
    Bundle args = new Bundle();
    args.putString("some_name", somename);
    customDialogFragment.setArguments(args);
    customDialogFragment.show(getSupportFragmentManager(), customDialogFragment.getTag());
    customDialogFragment.setCancelable(false); // if you don't wish to hide
    }
    

    Espérons que cela résout ce que vous essayez d'atteindre.

0voto

oumaya saratoon Points 33

Je ne sais pas si c'est ce que vous voulez mais peut-être qu'au lieu d'utiliser la transition, vous pouvez utiliser la fonction animate() car avec cette fonction, vous pouvez tout changer sur votre animation (temps, visibilité, etc.) .

0voto

akshat saini Points 1
 ## Translation Animation ##
<?xml version="1.0" encoding="utf-8"?>
<set
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:fillAfter="true"
    >
    <translate
        android:fromYDelta="100%p"
        android:toYDelta="-30%p"
        android:duration="900" />
</set>
 

## Activité principale ##

 @Override
protected void onResume() {
    super.onResume();
    Animation am= AnimationUtils.loadAnimation(this,R.anim.fadeout);
    tv5.startAnimation(am);
    Animation myanim= AnimationUtils.loadAnimation(this,R.anim.translate);
    tv1.startAnimation(myanim);
    myanim.setStartOffset(500);
    Animation animation= AnimationUtils.loadAnimation(this,R.anim.translate);
    animation.setStartOffset(1000);
    tv2.startAnimation(animation);
    Animation an= AnimationUtils.loadAnimation(this,R.anim.translate);
    an.setStartOffset(1500);
    tv3.startAnimation(an);
    Animation ab= AnimationUtils.loadAnimation(this,R.anim.translate);
    ab.setStartOffset(2000);
    tv4.startAnimation(ab);
    Animation ac= AnimationUtils.loadAnimation(this,R.anim.fadein);
    ac.setStartOffset(2500);
    btn1.startAnimation(ac);
}
 

0voto

Facile à mettre quelque chose sur le bas de l'écran, vous pouvez utiliser le code tel que:

final int activityHeight = findViewById(android.R.id.content).getHeight();
cardContainer.animate().yBy(activityHeight - cardContainer.getY()).setDuration(SLIDE_OUT_DURATION);

cardContainer , c'est la vue que vous essayez de glisser hors de l'écran.

Voir ce billet de blog pour l'exemple complet. Notez que vous pouvez également utiliser translationY au lieu de yBy. Un autre, plus générique façon de le faire est avec ce code:

public static ViewPropertyAnimator slideOutToBottom(Context ctx, View view) {
    final int screenHeight = ctx.getResources().getDisplayMetrics().heightPixels;
    int[] coords = new int[2];
    view.getLocationOnScreen(coords);
    return view.animate().translationY(screenHeight - coords[Y_INDEX]).setDuration(SLIDE_OUT_DURATION);
}

public static ViewPropertyAnimator slideInFromBottom(Context ctx, View view) {
    final int screenHeight = ctx.getResources().getDisplayMetrics().heightPixels;
    int[] coords = new int[2];
    view.getLocationOnScreen(coords);
    view.setTranslationY(screenHeight - coords[Y_INDEX]);
    return view.animate().translationY(0).setDuration(SLIDE_IN_DURATION).setInterpolator(new OvershootInterpolator(1f));
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X