どのようにこのカスタムビューの波のアニメーションを達成することができますか?

エンツォLizama:

私は波の真ん中に円でこのカスタム波のアニメーションを達成しようとしています。

ここでは、画像の説明を入力します。

以下は私のカスタムビューがあります。それは別の方向に実行され、引き分けは悪いUXでの結果という波の真ん中にラインを持っています。

私はいくつかの関連のチュートリアルに従うことを試みるが、私は同じアニメーションを取得することはできません。フォローするコードサンプルO任意のライブラリがある場合、それは私に多くのことを助けることができます。

ありがとうございました。

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.Region;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;

import com.guille.stressmeterapp.R;

import org.jetbrains.annotations.Nullable;


public class WaveCustomView extends View {

    private int mWidth = 0;
    private int mHeight = 0;
    private Path path;
    private Paint paint;
    private int waveHeight = 300;
    private int waveWidth = 600;



    private int originalY = 750;
    private Region region;
    private int dx = 0;
    private Bitmap mBitmap;


    private int animationDuration = 3000;

    public WaveCustomView(Context context) {
        super(context, null);
        initUi();
    }

    public WaveCustomView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs, 0);
        initUi();
    }

    public WaveCustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initUi();
    }

    private void initUi() {
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(Color.parseColor("#000000"));
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(15);
        path = new Path();
        mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.circle);
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int width;
        int height;

        if (widthMode == MeasureSpec.EXACTLY) {
            width = widthSize;
        } else {
            int desired = (int) (getPaddingLeft() + getPaddingRight());
            width = desired;
        }

        if (heightMode == MeasureSpec.EXACTLY) {
            height = heightSize;
        } else {
            int desired = (int) (getPaddingTop() + getPaddingBottom());
            height = desired;
        }
        mWidth = width;
        mHeight = height;
        waveWidth = mWidth / 2;
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawPath(path, paint);
        setDrawData();
        Rect bounds = region.getBounds();
        if (bounds.top < originalY) {
            canvas.drawBitmap(mBitmap,  bounds.right - (mBitmap.getWidth() >> 1), bounds.top - (mBitmap.getHeight() >> 1), paint);
        } else {
            canvas.drawBitmap(mBitmap, bounds.right - (mBitmap.getWidth() >> 1), bounds.bottom - (mBitmap.getHeight() >> 1), paint);
        }
    }

    private void setDrawData() {
        path.reset();
        int halfWaveWidth = waveWidth / 2;
        path.moveTo(-waveWidth + dx, originalY);

        for (int i = -waveWidth; i < mWidth + waveWidth; i = i + waveWidth) {
            path.rQuadTo(halfWaveWidth >> 1, -waveHeight, halfWaveWidth, 0);
            path.rQuadTo(halfWaveWidth >> 1, waveHeight, halfWaveWidth, 0);
        }
        region = new Region();
        Region clip = new Region((int) (mWidth / 2 - 0.1), 0, mWidth / 2, mHeight * 2);
        region.setPath(path, clip);
        path.close();
    }

    public void startAnimate() {
        ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
        animator.setRepeatCount(ValueAnimator.INFINITE);
        animator.setInterpolator(new LinearInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                float factor = (float) valueAnimator.getAnimatedValue();
                dx = (int) ((waveWidth) * factor);
                invalidate();
            }
        });
        animator.setDuration(animationDuration);
        animator.start();
    }
Askirov:

あなたのコードはOKに見えます。ただ、からこの行を削除setDrawDataする方法。

path.close();

この行は、パスを閉じます。これは、パスの末尾にbegginnigそれの接続パスを意味します。あなたは波の途中で行を参照してください理由です。ここでは中央の線なしの結果は次のとおりです。

ここでは、画像の説明を入力します。

あなたがアニメーションの方向を変更したい場合は、単にの符号変更するdx変数を。これを変える:

dx = (int) ((waveWidth) * factor);

これに:

dx = - (int) (waveWidth * factor);

またはその代わりに、この:

path.moveTo(-waveWidth + dx, originalY);

これを行う:

path.moveTo(-waveWidth - dx, originalY);

最終結果:

結果

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=337553&siteId=1