Background animation with repeat

Refresh

November 2018

Views

1.2k time

5

In my project, I would like to animate a background with a large image pattern indefinitely like this:

enter image description here

I thought initially use a Matrix (for scale and translate) with a ValueAnimator to create the translation animation but I have no idea how to repeat the pattern.

What is the way to develop this effect? Thank you for your help.


Update, my source code without repeat (Note: In the GIF animation I drew the image pattern horizontally for representation simplicities but I need a vertically translation animation in reality):

background.setImageResource(R.drawable.background);
background.setScaleType(ScaleType.MATRIX);

ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    private Matrix matrix = new Matrix();
    @Override public void onAnimationUpdate(ValueAnimator animation) {
        float factor = (Float) animation.getAnimatedValue();
        int width = background.getDrawable().getIntrinsicWidth();
        int height = background.getDrawable().getIntrinsicHeight();
        float scale = (float) background.getWidth() / (float) width;
        matrix.reset();
        matrix.postTranslate(0, -height * factor);
        matrix.postScale(scale, scale);
        background.setImageMatrix(matrix);
    }
});

animator.setInterpolator(new LinearInterpolator());
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.setRepeatMode(ValueAnimator.RESTART);
animator.setDuration(10000);
animator.start();

1 answers

2

Я, наконец, проходит BitmapDrawable переопределить метод дро ():

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.background);
BitmapDrawable drawable = new BitmapDrawable(getResources(), bitmap) {
    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        canvas.drawBitmap(getBitmap(), 0, getIntrinsicHeight(), null);
    }
};

background.setImageDrawable(drawable);
background.setScaleType(ScaleType.MATRIX);

ValueAnimator animator = ValueAnimator.ofFloat(0);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    private Matrix matrix = new Matrix();
    @Override
    public void onAnimationUpdate(ValueAnimator animator) {
        matrix.reset();
        int height = background.getDrawable().getIntrinsicHeight();
        float translate = -height * animator.getAnimatedFraction();
        matrix.postTranslate(0, translate);
        float width = background.getDrawable().getIntrinsicWidth();
        float scale = background.getWidth() / width;
        matrix.postScale(scale, scale);
        background.setImageMatrix(matrix);
    }
});

animator.setInterpolator(new LinearInterpolator());
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.setRepeatMode(ValueAnimator.RESTART);
animator.setDuration(10000);
animator.start();

Примечание: drawable.setTileModeXY(TileMode.REPEAT, TileMode.REPEAT)не работает с imageView.setScaleType(ScaleType.MATRIX).

Так что я не знаю, если это хорошая практика, но это только один я нашел на данный момент. Если у вас есть какие-либо идеи, чтобы улучшить технику, пожалуйста, поделитесь.