Как оптимизировать анимацию? - PullRequest
0 голосов
/ 17 апреля 2020

У меня есть collapsingToolbarLayout, и я хочу сделать анимацию, пока пользователь расширяет / сворачивает представление. Я добавил анимацию в addOnOffsetChangedListener, но проблема в том, что анимация не плавная. Например, на Свернуть imageview должен масштабироваться, затем альфа. Также он не должен менять свою позицию, поэтому для этого я использовал translationY. Хорошо, позвольте мне показать мой код. Я использую dataBinding.

binding.appbar.addOnOffsetChangedListener((abLayout, offset) -> {
        // Scale out the image and alpha.
        float scale = 1 - ((float) Math.abs(offset)/abLayout.getTotalScrollRange());
        binding.image.setTranslationY(Math.abs(offset));
        binding.image.animate().scaleX(scale).scaleY(scale).alpha(scale);

        if (Math.abs(offset) == abLayout.getTotalScrollRange()) {
            binding.labelNewsTitleToolbar.setVisibility(View.VISIBLE);
            binding.labelNewsTitle.setVisibility(View.INVISIBLE);
        } else if (Math.abs(offset) < abLayout.getTotalScrollRange()) {
            binding.labelNewsTitle.setVisibility(View.VISIBLE);
            binding.labelNewsTitleToolbar.setVisibility(View.INVISIBLE);
        }
        if (offset == 0)
            binding.image.animate().scaleX(1.0f).scaleY(1.0f).alpha(1.0f);
    });

Как я могу оптимизировать его, чтобы сделать более плавным? Когда я быстрее сворачиваю изображение, оно не может анимироваться во времени.

Ответы [ 2 ]

0 голосов
/ 19 апреля 2020

Почему бы вам не изменить значения alpha и scale напрямую (без анимации)? Ваша переменная scale зависит от смещения, и она изменяется от 0 до 1, поэтому я думаю, что все будет выглядеть гладко.

binding.appbar.addOnOffsetChangedListener((abLayout, offset) -> {
    float scale = 1 - ((float) Math.abs(offset)/abLayout.getTotalScrollRange());
    binding.image.setTranslationY(Math.abs(offset));
    binding.image.setScaleX(scale)
    binding.image.setScaleY(scale)
    binding.image.setSAlpha(scale);
    ....
}
0 голосов
/ 17 апреля 2020

Вы пробовали использовать тему? В переопределенном методе run() попытайтесь вызывать его 60 раз в секунду. Я использовал код ниже:

@Override
public void run() {
    double firstTime;
    double lastTime = System.nanoTime() / 1000000000d;
    double passedTime;
    double unprocessedTime = 0;
    deltaT = 0;
    while (running) {
        render = false;
        firstTime = System.nanoTime() / 1000000000d;
        passedTime = firstTime - lastTime;
        lastTime = firstTime;

        unprocessedTime += passedTime;
        frameTime += passedTime;
        //Frame time must be around 0.0166667
        if (frameTime <= 0.016667 && frameTime >= 0.01666) {
            deltaT = frameTime;
        }

        while (unprocessedTime >= UPDATE_CAP) {
            unprocessedTime -= UPDATE_CAP;
            render = true;

            if (frameTime >= 1d) {
                frameTime = 0;
                fps = frames;
                frames = 0;
            }
        }

        if (render) {
            //Render 
            //Call here the animation
            panel.repaint();
            frames++;
        }
    }
}

Внутри оператора if(render) вызовите метод анимации. Это хорошо сработало для меня, надеюсь, что то же самое для вас.

...