Εμφάνιση και απόκρυψη μιας προβολής με κίνηση slide up/down

Έχω ένα LinearLayout που θέλω να εμφανίζω ή να κρύβω με ένα Animation που σπρώχνει τη διάταξη προς τα πάνω ή προς τα κάτω κάθε φορά που αλλάζω την ορατότητά της.

Έχω δει μερικά δείγματα εκεί έξω, αλλά κανένα από αυτά δεν ταιριάζει στις ανάγκες μου.

Έχω δημιουργήσει δύο αρχεία xml για τα κινούμενα σχέδια αλλά δεν ξέρω πώς να τα ξεκινήσω όταν αλλάζω την ορατότητα ενός LinearLayout.

Λύση

Με το νέο API animation που εισήχθη στο Android 3.0 (Honeycomb) είναι πολύ απλό να δημιουργήσετε τέτοιες κινήσεις.

Ολίσθηση ενός View προς τα κάτω κατά μια απόσταση:

view.animate().translationY(distance);

Μπορείτε αργότερα να σύρετε το View πίσω στην αρχική του θέση ως εξής:

view.animate().translationY(0);

Μπορείτε επίσης να συνδυάσετε εύκολα πολλαπλά κινούμενα σχέδια. Το παρακάτω animation θα γλιστρήσει ένα View προς τα κάτω κατά το ύψος του και θα το ξεθωριάσει ταυτόχρονα:

// Prepare the View for the animation
view.setVisibility(View.VISIBLE);
view.setAlpha(0.0f);

// Start the animation
view.animate()
    .translationY(view.getHeight())
    .alpha(1.0f)
    .setListener(null);

Στη συνέχεια μπορείτε να ξεθωριάσετε το View και να το σύρετε πίσω στην αρχική του θέση. Ορίζουμε επίσης έναν AnimatorListener ώστε να μπορούμε να επαναφέρουμε την ορατότητα του View στο GONE μόλις τελειώσει η κίνηση:

view.animate()
    .translationY(0)
    .alpha(0.0f)
    .setListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
            view.setVisibility(View.GONE);
        }
    });
Σχόλια (22)

Μπορείτε να ξεκινήσετε το σωστό Animation όταν αλλάζει η ορατότητα του LinearLayout, δημιουργώντας μια νέα υποκλάση του LinearLayout και υπερισχύοντας της setVisibility() για να ξεκινήσετε το Animations. Σκεφτείτε κάτι τέτοιο:

public class SimpleViewAnimator extends LinearLayout
{
    private Animation inAnimation;
    private Animation outAnimation;

    public SimpleViewAnimator(Context context)
    {
        super(context);
    }

    public void setInAnimation(Animation inAnimation)
    {
        this.inAnimation = inAnimation;
    }

    public void setOutAnimation(Animation outAnimation)
    {
        this.outAnimation = outAnimation;
    }

    @Override
    public void setVisibility(int visibility)
    {
        if (getVisibility() != visibility)
        {
            if (visibility == VISIBLE)
            {
                if (inAnimation != null) startAnimation(inAnimation);
            }
            else if ((visibility == INVISIBLE) || (visibility == GONE))
            {
                if (outAnimation != null) startAnimation(outAnimation);
            }
        }

        super.setVisibility(visibility);
    }
}
Σχόλια (7)
if (filter_section.getVisibility() == View.GONE) {
    filter_section.animate()
            .translationY(filter_section.getHeight()).alpha(1.0f)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationStart(Animator animation) {
                    super.onAnimationStart(animation);
                    filter_section.setVisibility(View.VISIBLE);
                    filter_section.setAlpha(0.0f);
                }
            });
} else {
    filter_section.animate()
            .translationY(0).alpha(0.0f)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    filter_section.setVisibility(View.GONE);
                }
            });
}
Σχόλια (5)