Подтвердить что ты не робот

Выпуск анимации плавающего действия

Я играл с fab в библиотеке дизайна поддержки, когда я запустил эту проблему. Я заменил метод onCreate в шаблоне Blank Activity по умолчанию в Android Studio, это выглядит так:

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.animation.TranslateAnimation;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                TranslateAnimation anim = new TranslateAnimation(0, -500, 0, -500);
                anim.setDuration(1000);
                anim.setFillEnabled(true);
                anim.setFillAfter(true);
                fab.startAnimation(anim);
            }
        });
        fab.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                TranslateAnimation anim = new TranslateAnimation(0, -500, 0, -500);
                anim.setDuration(1000);
                anim.setFillEnabled(true);
                anim.setFillAfter(true);
                fab.startAnimation(anim);
                return true;
            }
        });
    }
}

Итак, в основном, я добавил onClickListener и onLongClickListener, которые переводят fab на 500idks, но проблема в том, что он не работает так, как предполагалось.

Когда я нажимаю на него, обычно ничего не происходит, что странно начинать с. Здесь есть видео.

Когда я долго нажимаю на него, он оживляет, как я должен, но только если я продолжаю нажимать, и всякий раз, когда я поднимаю палец, он возвращается к исходной позиции независимо от того, завершена ли анимация или нет, хотя я установил setFillEnabled(true) и setFillAfter(true).

Вот видео о том, что происходит, когда я поднимаю мой палец и когда я оставьте мой палец на экране до конца и все.

Animation

Почему это происходит?

4b9b3361

Ответ 1

Я не знаю, почему вы получаете эту проблему с анимацией, но она выглядит как ошибка. Я проверил ваш код, и он работает на моем Android 6.0, но он не работает на Android Emulator с Android 4.4 на борту (но мой вопрос немного отличается от вашего).

Итак, мое предположение это ошибка, потому что TranslateAnimation имел (и может быть, еще) некоторые ошибки вроде один, два.

И мое предложение, как вы можете избежать этого, следующее. Используйте ViewPropertyAnimator, чтобы оживить ваши представления. И ваш код в этом случае должен выглядеть так:

    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            fab.animate()
                    .translationX(-500)
                    .translationY(-500)
                    .setDuration(1000)
                    .start();
        }
    });
    fab.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View view) {
            fab.animate()
                    .translationX(-500)
                    .translationY(-500)
                    .setDuration(1000)
                    .start();
            return true;
        }
    });

Я проверил его на Android Emulator с Android 4.3, 4.4, 5.0, 6.0, и он отлично работает.

Обновление

Найдено решение для вас. Таким образом, вы можете использовать ViewPropertyAnimatorCompat из библиотеки поддержки, и ваш код будет похож на:

fab.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
            ViewCompat.animate(fab)
                    .translationX(-500)
                    .translationY(-500)
                    .setDuration(1000)
                    .start();
    }
});
fab.setOnLongClickListener(new View.OnLongClickListener() {
    @Override
    public boolean onLongClick(View view) {
            ViewCompat.animate(fab)
                    .translationX(-500)
                    .translationY(-500)
                    .setDuration(1000)
                    .start();
        return true;
    }
});

Ответ 2

Обновить: теперь предположим, что он исправлен в поддержке lib 24.2.0 после ошибки, которую я открыл: https://code.google.com/p/android/issues/detail?id=215043

==============

Для тех из нас, кому не повезло просто заменить их анимацию на ViewPropertyAnimation как я:

Эта ошибка возникает из-за ошибки в реализации поддержки FloatingActionButton, определенной в FloatingActionButtonEclairMr1 класс, в котором настройка анимации для всех состояний представления, поэтому при нажатии на просмотр есть анимация FloatingActionButtonEclairMr1.ElevateToTranslationZAnimation, которая запускается, поэтому ваша анимация очищается от представления.

Самое простое решение, которое я нахожу, просто запускает вашу анимацию с некоторой задержкой НЕ с startOffset (потому что она по-прежнему будет переопределяться нажатием анимации), но с вызовом анимации с задержкой (я использую 100, но также проверяю с 60, и это сработало. 20 недостаточно):

    final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //Probably want to do it just for pre Lolipop
            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    TranslateAnimation anim = new TranslateAnimation(0, -500, 0, -500);
                    anim.setDuration(1000);
                    anim.setFillEnabled(true);
                    anim.setFillAfter(true);
                    fab.startAnimation(anim);
                }
            }, 100);
        }
    });
    fab.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View view) {
            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    TranslateAnimation anim = new TranslateAnimation(0, -500, 0, -500);
                    anim.setDuration(1000);
                    anim.setFillEnabled(true);
                    anim.setFillAfter(true);
                    fab.startAnimation(anim);
                }
            }, 100);
        }
    });

Ответ 3

Я думаю, что вы должны держать объект anim в качестве переменной уровня класса, onLongClick() и onClick() во многих случаях вызывается в перекрывающемся режиме. Поскольку у вас разные объекты-объекты, вы получаете доступ к той же фабрике из двух объектов-аниматоров.

Держите анимацию снаружи и разместите свое наблюдение.

и попробуйте удалить методы onLongClick() или onClick(). если возможно, добавьте журнал этих двух методов, чтобы понять последовательность вызовов.

Я буду ждать ваших наблюдений.

Ответ 4

Возможно, это относится к вашей проблеме: SO-Thread

Я использую AnimatorListener для установки позиции представления после законченной анимации.

.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {

        }

        @Override
        public void onAnimationEnd(Animator animation) {
            // set Position
        }

        @Override
        public void onAnimationCancel(Animator animation) {

        }

        @Override
        public void onAnimationRepeat(Animator animation) {

        }
    });

Я вижу только фрагмент кода. Для вашей проблемы с onClickListener я проверил бы, если вы установили андроид: clickable = "false" внутри вашего xml или если вы внедрили еще один OnClickListener.

Ответ 5

Для выполнения этой работы вам нужно использовать ViewPropertyAnimator. Анимация фактически не перемещает представление, а просто растровое представление представления, как описано здесь.