Fade In Fade Out Android-анимация в Java

148

Я хочу иметь 2-секундную анимацию ImageView, которая затухает 1000 мс, а затем затухает 1000 мс.

Вот что у меня есть в конструкторе ImageView:

Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setDuration(1000);

Animation fadeOut = new AlphaAnimation(1, 0);
fadeOut.setStartOffset(1000);
fadeOut.setDuration(1000);

AnimationSet animation = new AnimationSet(true);
animation.addAnimation(fadeIn);
animation.addAnimation(fadeOut);
this.setAnimation(animation);

Когда я запускаю эту анимацию, ничего не появляется. Однако, когда я удаляю одну из альфа-анимаций, поведение работает так, как ожидалось.

Вещи, которые я уже пробовал:

  • Все мыслимые комбинации setFillBefore, setFillAfterи setFillEnabled.
  • Добавление LinearInterpolatorк AnimationSet.
пахарь
источник
1
Да, вы можете выцветать и исчезать! Этот урок должен сделать свое дело. sankarganesh-info-exchange.blogspot.com/2011/04/…
Адам Сторм
Этот учебник описывает метод с использованием XML. Вы знаете, как добиться того же, используя Java?
пахарь
Ну, я не рядом с моим компьютером программирования, поэтому я не могу проверить этот код, но вы можете установить атрибуты XML в Java. это оригинальный код: android: interpolator = "@ android: anim / accelerate_interpolator" android: fromAlpha = "0.0" android: toAlpha = "1.0" android: duration = "300" /> \ n, так что вы, вероятно, можете MyTween.setDurationg (300) MyTween.fromAlpha (0.0) MyTween (1.0)
Адам Шторм

Ответы:

258

Разобрался с собственной проблемой. Решение оказалось в основе интерполяторов.

Animation fadeIn = new AlphaAnimation(0, 1);
fadeIn.setInterpolator(new DecelerateInterpolator()); //add this
fadeIn.setDuration(1000);

Animation fadeOut = new AlphaAnimation(1, 0);
fadeOut.setInterpolator(new AccelerateInterpolator()); //and this
fadeOut.setStartOffset(1000);
fadeOut.setDuration(1000);

AnimationSet animation = new AnimationSet(false); //change to false
animation.addAnimation(fadeIn);
animation.addAnimation(fadeOut);
this.setAnimation(animation);


Если вы используете Kotlin

val fadeIn = AlphaAnimation(0f, 1f)
fadeIn.interpolator = DecelerateInterpolator() //add this
fadeIn.duration = 1000

val fadeOut = AlphaAnimation(1f, 0f)
fadeOut.interpolator = AccelerateInterpolator() //and this
fadeOut.startOffset = 1000
fadeOut.duration = 1000

val animation = AnimationSet(false) //change to false
animation.addAnimation(fadeIn)
animation.addAnimation(fadeOut)
this.setAnimation(animation)
пахарь
источник
1
Что, если вы хотите сделать 5 или 6 постепенных затуханий с действительно небольшими задержками, например, 100 для каждого, можете ли вы использовать что-то подобное? Я пытался, но это не совсем жидкость. Цель состояла в том, чтобы имитировать, например, лампочку, которая не будет работать должным образом, и мерцать.
Chayy
попробуйте вызвать this.setAnimation в цикле
Джонатан
Я думал, что я исчезаю в последнем bg img и fad в текущем, но этот ответ вдохновляет меня на то, что мне нужно только исчезнуть в текущем bg img и исчезнуть в текущем, потому что AlphaAnimation не может исчезнуть / вывести два разных imgs ,
macio.Jun
8
Я не думаю, что вам нужно иметь две независимые анимации ... Я думаю, что вы могли бы иметь одну анимацию и установить параметр: fadeInOut.setRepeatMode (Animation.REVERSE);
RoundSparrow Hilltx
Второе: если вы хотите повторить, не нужно вызывать цикл, как сказал @jonney. используйте fadeInOut.setRepeatCount (6) - измените 6 на то, сколько вы хотите повторить. Гораздо меньше накладных расходов, чтобы родной код C ++ в Android делал все это вместо вызова в цикле Java.
RoundSparrow Hilltx
137

Я знаю, что на это уже был дан ответ, но .....

<?xml version="1.0" encoding="utf-8"?> 
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromAlpha="1.0" 
    android:toAlpha="0.0" 
    android:duration="1000"    
    android:repeatCount="infinite" 
    android:repeatMode="reverse"
    />

Быстрый и простой способ быстро сделать появление и исчезновение с повторением себя. наслаждаться

РЕДАКТИРОВАТЬ : В вашей деятельности добавить это:

yourView.startAnimation(AnimationUtils.loadAnimation(co‌​ntext, R.anim.yourAnimation));
Конрад Винковски
источник
6
+1 Потому что с этим ответом я мог сделать последовательность постепенного появления, постепенного исчезновения и постепенного появления (просто устанавливая repeatCount = "2"). Я не мог объединить анимацию, как предлагает принятый ответ.
ElYeante
1
После объявления этого alphaресурса, как я могу его использовать? Спасибо
zozelfelfo
1
zozelfelfo, это всего лишь анимационный XML, поэтому загрузите его в код, а затем вызовите startAnimation для любого представления, на которое вы хотите, чтобы оно влияло.
Конрад Винковски
@KonradWinkowski метод startAnimation требует использования объекта Animation в качестве аргумента! что я должен передать ему?
Ахмад Ватани
Для тех, кто ищет более полный ответ: viewToAnimate.startAnimation(AnimationUtils.loadAnimation(context, R.anim.fade_in_out)где в папке anim под res находится файл fade_in_out.xml.
Крис Найт
32
viewToAnimate.animate().alpha(1).setDuration(1000).setInterpolator(new DecelerateInterpolator()).withEndAction(new Runnable() {
    @Override
    public void run() {
        viewToAnimate.animate().alpha(0).setDuration(1000).setInterpolator(new AccelerateInterpolator()).start();
    }
}).start();
Виталий Зинченко
источник
4
Elegante для зефира!
Позволяет
26

Вот мое решение с использованием AnimatorSet, которое кажется немного более надежным, чем AnimationSet.

// Custom animation on image
ImageView myView = (ImageView)splashDialog.findViewById(R.id.splashscreenImage);

ObjectAnimator fadeOut = ObjectAnimator.ofFloat(myView, "alpha",  1f, .3f);
fadeOut.setDuration(2000);
ObjectAnimator fadeIn = ObjectAnimator.ofFloat(myView, "alpha", .3f, 1f);
fadeIn.setDuration(2000);

final AnimatorSet mAnimationSet = new AnimatorSet();

mAnimationSet.play(fadeIn).after(fadeOut);

mAnimationSet.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
        super.onAnimationEnd(animation);
        mAnimationSet.start();
    }
});
mAnimationSet.start();
Твилли
источник
Мне пришлось использовать ObjectAnimator вместо Animation, чтобы получить рабочее решение, потому что по какой-то причине, когда я запускал AlphaAnimation, он запускался дважды и делал странные мерцания.
Андрей Оробатор
элегантное решение
Влад
Ну, это слишком поздно, но я думаю, что это может помочь некоторым, любезно прояснить анимацию, прежде чем использовать ее снова на том же виде ..
Бхавеш Морадия
21

Другая альтернатива:

Нет необходимости определять 2 анимации для fadeIn и fadeOut . fadeOut - это обратная сторона fadeIn .

Таким образом, вы можете сделать это с Animation.REVERSE следующим образом:

AlphaAnimation alphaAnimation = new AlphaAnimation(0.0f, 1.0f);
alphaAnimation.setDuration(1000);
alphaAnimation.setRepeatCount(1);
alphaAnimation.setRepeatMode(Animation.REVERSE);
view.findViewById(R.id.imageview_logo).startAnimation(alphaAnimation);

затем onAnimationEnd :

alphaAnimation.setAnimationListener(new Animation.AnimationListener() {
    @Override
        public void onAnimationStart(Animation animation) {
            //TODO: Run when animation start
        }

        @Override
        public void onAnimationEnd(Animation animation) {
            //TODO: Run when animation end
        }

        @Override
        public void onAnimationRepeat(Animation animation) {
            //TODO: Run when animation repeat
        }
    });
MarsPeople
источник
12

Как я полагаю, в силу XML (для макетов), это эквивалентно принятому ответу , но чисто как ресурс анимации:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:interpolator/accelerate_decelerate"
    android:fillAfter="true">
    <alpha
        android:fromAlpha="0"
        android:toAlpha="1"
        android:duration="1000" />
    <alpha
        android:fromAlpha="1"
        android:toAlpha="0"
        android:duration="1000"
        android:startOffset="1000"/>
</set>

fillAfterДля увядания остаться после завершения анимации. Как вы можете догадаться, interpolatorобрабатывает интерполяцию анимации. Вы также можете использовать другие типы интерполяторов, такие как линейный или Overshoot.

Обязательно запустите анимацию на виде:

yourView.startAnimation(AnimationUtils.loadAnimation(co‌​ntext, R.anim.fade));
DarkCygnus
источник
@KGCybeX нет проблем, рад, что смог помочь :)
DarkCygnus
1
Очень полезно и чисто. Отлично работает для меня
Фернандо Барбоза
9

Вот то, что я использовал для постепенного исчезновения в представлениях, надеюсь, это кому-нибудь поможет.

private void crossFadeAnimation(final View fadeInTarget, final View fadeOutTarget, long duration){
    AnimatorSet mAnimationSet = new AnimatorSet();
    ObjectAnimator fadeOut = ObjectAnimator.ofFloat(fadeOutTarget, View.ALPHA,  1f, 0f);
    fadeOut.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {
        }

        @Override
        public void onAnimationEnd(Animator animation) {
            fadeOutTarget.setVisibility(View.GONE);
        }

        @Override
        public void onAnimationCancel(Animator animation) {
        }

        @Override
        public void onAnimationRepeat(Animator animation) {
        }
    });
    fadeOut.setInterpolator(new LinearInterpolator());

    ObjectAnimator fadeIn = ObjectAnimator.ofFloat(fadeInTarget, View.ALPHA, 0f, 1f);
    fadeIn.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {
            fadeInTarget.setVisibility(View.VISIBLE);
        }

        @Override
        public void onAnimationEnd(Animator animation) {}

        @Override
        public void onAnimationCancel(Animator animation) {}

        @Override
        public void onAnimationRepeat(Animator animation) {}
    });
    fadeIn.setInterpolator(new LinearInterpolator());
    mAnimationSet.setDuration(duration);
    mAnimationSet.playTogether(fadeOut, fadeIn);
    mAnimationSet.start();
}
Кристиан Эскобар
источник
Каким-то образом это единственный ответ, который включает настройку видимости, хорошо
Лука
8

Наборы анимации не работают должным образом. В конце я сдался и использовал postDelayed () класса Handler для последовательности анимаций.

Ричард
источник
8

Если вы используете Animator для создания анимации, вы можете

anim (каталог) -> fade_out.xml

<?xml version="1.0" encoding="UTF-8"?>
<objectAnimator
    android:propertyName="alpha"
    android:valueFrom="0"
    android:valueTo="1"
    xmlns:android="http://schemas.android.com/apk/res/android"/>

В яве

Animator animator = AnimatorInflater.loadAnimator(context, R.animator.fade_out);
animator.setTarget(the_view_you_want_to_animation);
animator.setDuration(1000);
animator.start();

Другой способ заставить анимацию исчезать только с помощью Java-кода:

ObjectAnimator fadeOut = ObjectAnimator.ofFloat(the_view_you_want_to_animation, "alpha",  1f, 0);
fadeOut.setDuration(2000);
fadeOut.start();
Фан Ван Линь
источник
в каталоге аним * не аниматор
косас
4

Вы также можете использовать animationListener, что-то вроде этого:

fadeIn.setAnimationListener(new AnimationListener() {
    @Override
    public void onAnimationEnd(Animation animation) {
        this.startAnimation(fadeout);
    }
});
Омид Аминива
источник
0

Мне очень нравится решение Виталия Зинченко, так как оно было коротким.

Вот еще более короткая версия в kotlin для простого исчезновения

viewToAnimate?.alpha = 1f
viewToAnimate?.animate()
             ?.alpha(0f)
             ?.setDuration(1000)
             ?.setInterpolator(DecelerateInterpolator())
             ?.start()
Марк
источник