2010-10-07 3 views
48

J'utilise une animation définie au format XML pour faire glisser une vue hors de l'écran. Le problème est que, dès que l'animation est terminée, elle se réinitialise à sa position d'origine. J'ai besoin de savoir comment réparer ça. Voici le xml:Android: réinitialisation de position d'animation après achèvement

<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator"> 
    <translate android:fromXDelta="0" android:toXDelta="-100%p" android:duration="500"/></set> 

Voici le Java que j'utiliser pour l'appeler:

homeScrn = (View)findViewById(R.id.homescreen); 
    slideLeftOut = AnimationUtils.loadAnimation(this, R.anim.slide_left_out); 

    //Set Click Listeners For Menu 
    btnHelp.setOnClickListener(new OnClickListener() { 
     public void onClick(View v) { 
      LayoutInflater.from(getApplicationContext()).inflate(R.layout.help, (ViewGroup)findViewById(R.id.subpage), true); 
      homeScrn.startAnimation(slideLeftOut); 
     } 
    }); 

Donc, fondamentalement, ce qui se passe est une vue je gonfle sous l'un. Ensuite, j'anime la vue en haut à gauche. Dès qu'il sort de l'écran et que l'animation est terminée, il réinitialise sa position.

Répondre

69

Les animations fonctionnent comme prévu. Juste parce que vous avez animé quelque chose ne signifie pas que vous l'avez réellement déplacé. Une animation n'affecte que les pixels dessinés pendant l'animation elle-même, et non la configuration des widgets.

Vous devez ajouter un AnimationListener, et dans la méthode onAnimationEnd(), faire quelque chose qui rend votre déménagement permanent (par exemple, supprime la vue sur le dessus de son parent, marque le point de vue sur le dessus comme ayant une visibilité GONE).

+0

ah ha! exactement ce dont j'avais besoin. Merci! – LoneWolfPR

+4

Mais que dois-je faire si le même doit glisser. puisque ce n'est pas réellement déplacé alors comment puis-je glisser dans l'objet que j'ai slideOut ??? – Ads

+0

Même si vous faites * permeneny * déplacer votre 'View' dans' onAnimationEnd() 'il clignote **. Vérifiez: http://stackoverflow.com/questions/2650351/android-translateanimation-resets-after-animation –

14

je pourrais être un peu tard lui répondre, mais j'ai la solution pour cela:

Ajoutez juste android:fillAfter=true dans votre xml

+14

Cela ne fonctionne pas pour l'animation de traduction. Cela ne fonctionne que pour Scale Animation. – Ads

+3

il ne fonctionne pas pour tourner non plus. –

+1

Cela fonctionne pour la rotation. –

1

Je suis allé à la même question et résolu avec le réglage de la marginLeft à OnAnimationEnd() ..

MarginLayoutParams params = (MarginLayoutParams) this.getLayoutParams(); params.setMargins(this.getWidth()*position, 0,0,0); this.setLayoutParams(params);

9

Vous pouvez utiliser

fillAfter=true 
fillEnabled=true 

votre vue ne sera pas réinitialisée à la position d'origine, mais si vous avez des boutons ou quelque chose d'autre dans votre vue, leur position ne changera pas.

Vous devez utiliser ObjectAnimator, cela fonctionne à partir du niveau API 11.Il change Voir position automatique,

ici est l'exemple

ObjectAnimator objectAnimator= ObjectAnimator.ofFloat(mContent_container, "translationX", startX, endX); 
objectAnimator.setDuration(1000); 
objectAnimator.start(); 

Merci JUL son answer

Si votre application ne se trouve pas object animator, modifiez le niveau de l'API de Project -> properties -> Android, que import android.animation.ObjectAnimator;

Regards Hayk

88

Enfin obtenu un moyen de contourner le problème, le bonne façon de le faire est setFillAfter(true),

si vous souhaitez définir votre animation en XML, alors vous devriez faire quelque chose comme ça

<set xmlns:android="http://schemas.android.com/apk/res/android" 
    android:interpolator="@android:anim/decelerate_interpolator" 
    android:fillAfter="true"> 

    <translate 
     android:fromXDelta="0%" 
     android:toXDelta="-100%" 
     android:duration="1000"/> 

</set> 

vous pouvez voir que je l'ai défini filterAfter="true" dans le set tag, si vous essayez de le définir dans translate tag cela ne fonctionnera pas, pourrait être un bug dans le cadre !!

puis dans le Code

Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide_out); 
someView.startAnimation(anim); 

OU

TranslateAnimation animation = new TranslateAnimation(-90, 150, 0, 0); 

animation.setFillAfter(true); 

animation.setDuration(1800); 

someView.startAnimation(animation); 

alors il va sûrement travailler !! Maintenant, c'est un peu difficile, il semble que la vue se déplace réellement à la nouvelle position, mais en fait les pixels de la vue sont déplacés, c'est-à-dire que votre vue est réellement à sa position initiale mais pas visible. avez-vous appuyer sur un bouton ou une vue cliquable dans votre vue (dans mon cas dans la mise en page), de fixer que vous devez déplacer manuellement votre point de vue/mise en page à la nouvelle position

public TranslateAnimation (float fromXDelta, float toXDelta, float fromYDelta, float toYDelta) 

new TranslateAnimation(-90, 150, 0, 0); 

maintenant que nous pouvons voir que notre animation commence à partir de -90 x-axe à 150 x-axe

alors ce que nous faisons est

someView.setAnimationListener(this); 

et

public void onAnimationEnd(Animation animation) 
{ 
    someView.layout(150, 0, someView.getWidth() + 150, someView.getHeight()); 
} 

maintenant laissez-moi vous expliquer public void layout (int left, int top, int right, int botton)

se déplace votre mise en page à nouveau premier argument de position définir la gauche, que nous est , parce que traduire l'animation a animé notre avis à 150 x-axe, top est 0 parce que nous n'avons pas animé y-axe, maintenant en droit nous avons fait someView.getWidth() + 150 fondamentalement nous obtenons la largeur de notre vue et ajouté parce que nous notre gauche est maintenant passer à 150 x-axe pour faire de la largeur de la vue à son origine, et le bas est égal à la hauteur de notre vue.

Je vous souhaite maintenant les gens ont compris le concept de traduction, et encore vous avez des questions que vous pouvez poser tout de suite dans la section commentaire, je me sens le plaisir d'aider :)

EDIT Ne pas utiliser layout() méthode comme il peut être appelé par le cadre quand jamais la vue est invalidée et que vos changements ne se verront pas, utilisez LayoutParams pour définir vos paramètres de disposition en fonction de vos besoins

+2

Meilleure réponse pour ce scénario. – Vivekanand

+0

Merci pour l'explication que j'utilise cette approche aussi, seul problème avec cette approche est lorsque l'animation est terminée scintillement animés de vue. – user65721

+1

@ user65721 déplacez-vous votre vue à un nouvel emplacement ?? et avez-vous essayé 'setFillEnabled()' ?? –

1

Ce problème a dérangé pendant plus d'une semaine. Et la réponse de Muhammad m'a indiqué une manière directe de le résoudre.

J'ai utilisé la mise en page de découpage pour implémenter des menus latéraux avec animation. "view.layout ne sera pas persistant, vous devriez utiliser LayoutParams, qui sera persistant."

Voici ma solution: (Utiliser ce type de LayoutParameter est dépendait de votre propre mise en page des parents):

@Override 
public void onAnimationEnd(Animation animation) { 
FrameLayout.LayoutParams layoutParams=new FrameLayout.LayoutParams(screenWidth, screenHeight); 
layoutParams.setMargins((int) -(screenWidth * RATE), 0, 
      (int) (screenWidth - screenWidth * RATE), screenHeight); 
    for(View v:views) { 

     v.setLayoutParams(layoutParams); 
     //v.layout((int) -(screenWidth * RATE), 0, (int) (screenWidth - screenWidth * RATE), screenHeight); 
     v.clearAnimation(); 
    } 
} 
5

Vous devez ajouter cette commande:

final Animation animSlideLeft = new TranslateAnimation(0, -80, 0,-350, 0, 0, 0, 0); 
animSlideLeft.setFillAfter(true); 
Questions connexes