web-dev-qa-db-fra.com

Pourquoi setVisibility ne fonctionne-t-il pas après l'animation d'une vue?

Pourquoi le textView ne devient-il pas invisible?

Voici ma mise en page xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:orientation="vertical" >

    <TextView
    Android:id="@+id/tvRotate"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:text="Rotate Me"
/>
</LinearLayout>

..et voici mon activité:

public class RotateMeActivity extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        TextView tvRotate = (TextView) findViewById(R.id.tvRotate);

        RotateAnimation r = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        r.setDuration(0);
        r.setFillAfter(true);
        tvRotate.startAnimation(r);
        tvRotate.setVisibility(View.INVISIBLE);
    }
}

Mon objectif est de faire pivoter une vue, puis de la masquer et de l'afficher dans le code en définissant setVisibility. Les travaux suivants, mais setRotation est disponible uniquement dans l'API niveau 11. J'ai besoin d'un moyen de le faire dans l'API niveau 10.

tvRotate.setRotation(180);//instead of the RotateAnimation, only works in API Level 11
tvRotate.setVisibility(View.INVISIBLE);
63
ZippyFerguson

Pour moi, appeler clearAnimation de la vue a résolu le problème. Dans mon cas, je voulais remettre la vue dans sa position d'origine après avoir fait une traduction avec fillAfter réglé sur true.

161
Jeroen

Toutes les animations (avant Android 3.0) sont en fait appliquées à un bitmap qui est un instantané de votre vue plutôt que sur votre vue d'origine. Lorsque vous définissez le remplissage après sur true, cela signifie en fait que le bitmap continuera à être affiché à l'écran au lieu de votre vue. C'est la raison pour laquelle la visibilité ne changera pas lors de l'utilisation de setVisibility et aussi la raison pour laquelle votre vue ne recevra pas d'événements tactiles dans sa nouvelle (tourné) (mais comme vous tournez à 180 degrés, ce n'est pas un problème).

21
asenovm

Une autre façon de contourner ce problème consiste à encapsuler votre vue animée dans une autre vue et à définir la visibilité de cette vue wrapper.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
     Android:layout_width="match_parent"
     Android:layout_height="match_parent"
     Android:orientation="vertical" >
    <FrameLayout 
        Android:id="@+id/animationHoldingFrame"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content">
        <TextView
             Android:id="@+id/tvRotate"
             Android:layout_width="wrap_content"
             Android:layout_height="wrap_content"
             Android:text="Rotate Me"
        />
    </FrameLayout>
</LinearLayout>

Et le code devient alors ceci:

TextView tvRotate = (TextView) findViewById(R.id.tvRotate);
FrameLayout animationContainer = (FrameLayout)findViewById(R.id.animationHoldingFrame)

RotateAnimation r = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
r.setDuration(0);
r.setFillAfter(true);
tvRotate.startAnimation(r);
animationContainer.setVisibility(View.INVISIBLE);
8
Chris Knight

Utilisez ceci avant setVisibility une fois l'animation terminée:

anim.reverse();
anim.removeAllListeners();
anim.end();
anim.cancel();

où anim est votre ObjectAnimator

mais si vous utilisez la classe Animation, faites simplement:

view.clearAnimation();

sur la vue sur laquelle l'animation a été réalisée

6
user3567365

J'ai fini par exiger l'API de niveau 11 et utiliser setRotation pour y parvenir. Cela semble être une exigence assez simple qui ne peut pas être effectuée avant Honeycomb. Tout ce que je voulais faire était de faire pivoter un bouton, puis de le cacher/montrer.

1
ZippyFerguson

J'ai trouvé une solution pour cela: fondamentalement juste avant d'appeler setVisibility (View.GONE), faites une animation avec duration = 0 setFillAfter (false) et ayez l'angle de/à défini sur l'angle de rotation actuel.

Cela effacera le bitmap setFillAfter et permettra à la vue de disparaître.

1
Grantland Chew