实战属性动画与自定义控件相结合波浪

来源:互联网 发布:购物秒杀软件 编辑:程序博客网 时间:2024/05/17 21:43

 

多说不如直接上代码

 

初始化属性动画:

 List<Animator> animators =new ArrayList<>();

        // horizontal animation.
        // wave waves infinitely.
        ObjectAnimator waveShiftAnim = ObjectAnimator.ofFloat(
                mWaveView,"waveShiftRatio",0f,1f);
        waveShiftAnim.setRepeatCount(ValueAnimator.INFINITE);
        waveShiftAnim.setDuration(5000);
        waveShiftAnim.setInterpolator(newLinearInterpolator());
        animators.add(waveShiftAnim);

        // vertical animation.
        // water level increases from 0 to center of WaveView
        ObjectAnimator waterLevelAnim = ObjectAnimator.ofFloat(
                mWaveView,"waterLevelRatio",0f,0.5f);
//        waterLevelAnim.setDuration(10000);
        waterLevelAnim.setInterpolator(newDecelerateInterpolator());
        animators.add(waterLevelAnim);

        // amplitude animation.
        // wave grows big then grows small, repeatedly
        ObjectAnimator amplitudeAnim = ObjectAnimator.ofFloat(
                mWaveView,"amplitudeRatio",0.0001f,0.05f);
        amplitudeAnim.setRepeatCount(ValueAnimator.INFINITE);
        amplitudeAnim.setRepeatMode(ValueAnimator.REVERSE);
        amplitudeAnim.setDuration(5000);
        amplitudeAnim.setInterpolator(newLinearInterpolator());
        animators.add(amplitudeAnim);

        mAnimatorSet= newAnimatorSet();
        mAnimatorSet.playTogether(animators);

 

 

 

在创建这些属性动画的时候,注意要对相对应得自定义书属性创建相对应的set方法:

 

public floatgetWaveShiftRatio() {
    returnmWaveShiftRatio;
}

/**
 * Shift the wave horizontally according to<code>waveShiftRatio</code>.
 *
 *
@paramwaveShiftRatio Should be 0 ~ 1. Default to be 0.
 *                       <br/>Result of waveShiftRatio multiples width of WaveView is the length to shift.
 */
public void setWaveShiftRatio(floatwaveShiftRatio) {
    if(mWaveShiftRatio!= waveShiftRatio) {
        mWaveShiftRatio= waveShiftRatio;
        invalidate();
    }
}

public float getWaterLevelRatio() {
    returnmWaterLevelRatio;
}

/**
 * Set water level according to <code>waterLevelRatio</code>.
 *
 *
@paramwaterLevelRatio Should be 0 ~ 1. Default to be 0.5.
 *                        <br/>Ratio of water level to WaveView height.
 */
public void setWaterLevelRatio(floatwaterLevelRatio) {
    if(mWaterLevelRatio!= waterLevelRatio) {
        mWaterLevelRatio= waterLevelRatio;
        invalidate();
    }
}

public float getAmplitudeRatio() {
    returnmAmplitudeRatio;
}

/**
 * Set vertical size of wave according to<code>amplitudeRatio</code>
 *
 *
@paramamplitudeRatio Default to be 0.05. Result of amplitudeRatio + waterLevelRatio should be less than 1.
 *                       <br/>Ratio of amplitude to height of WaveView.
 */
public void setAmplitudeRatio(floatamplitudeRatio) {
    if(mAmplitudeRatio!= amplitudeRatio) {
        mAmplitudeRatio= amplitudeRatio;
        invalidate();
    }
}

public float getWaveLengthRatio() {
    returnmWaveLengthRatio;
}

/**
 * Set horizontal size of wave according to<code>waveLengthRatio</code>
 *
 *
@paramwaveLengthRatio Default to be 1.
 *                        <br/>Ratio of wave length to width of WaveView.
 */
public void setWaveLengthRatio(floatwaveLengthRatio) {
    mWaveLengthRatio= waveLengthRatio;
}

public boolean isShowWave() {
    returnmShowWave;
}

public void setShowWave(booleanshowWave) {
    mShowWave= showWave;
}

 

 

在自定义波浪中首先创建画笔功工具:

private voidinit() {
    mShaderMatrix= newMatrix();
    mViewPaint= newPaint();
    mViewPaint.setAntiAlias(true);
}

 

/**
 * Create the shader with default waves which repeat horizontally, and clamp vertically
 */
private void createShader() {
    mDefaultAngularFrequency= 2.0f* Math.PI/ DEFAULT_WAVE_LENGTH_RATIO/ getWidth();
    mDefaultAmplitude= getHeight() * DEFAULT_AMPLITUDE_RATIO;
    mDefaultWaterLevel= getHeight() * 0.9f;
    mDefaultWaveLength= getWidth();

    Bitmap bitmap = Bitmap.createBitmap(getWidth(),getHeight(),Bitmap.Config.ARGB_8888);
    Canvas canvas =new Canvas(bitmap);

    Paint wavePaint =new Paint();
    wavePaint.setStrokeWidth(2);
    wavePaint.setAntiAlias(true);

    // Draw default waves into the bitmap
    // y=Asin(ωx+φ)+h
    final intendX = getWidth() + 1;
    final int endY = getHeight() +1;

    float[] waveY =new float[endX];

    wavePaint.setColor(mBehindWaveColor);
    for (intbeginX = 0;beginX < endX;beginX++) {
        doublewx = beginX * mDefaultAngularFrequency;
        float beginY = (float) (mDefaultWaterLevel+ mDefaultAmplitude* Math.sin(wx));
        canvas.drawLine(beginX,beginY,beginX,endY,wavePaint);

        waveY[beginX] = beginY;
    }

    wavePaint.setColor(mFrontWaveColor);
    final int wave2Shift = (int) (mDefaultWaveLength/ 4);
    for (intbeginX = 0;beginX < endX;beginX++) {
        canvas.drawLine(beginX,waveY[(beginX + wave2Shift) % endX],beginX,endY,wavePaint);
    }

    // use the bitamp to create the shader
    mWaveShader= newBitmapShader(bitmap,Shader.TileMode.REPEAT,Shader.TileMode.CLAMP);
    mViewPaint.setShader(mWaveShader);
}

 

工具创建完之后,对布局的刻画以及布局改变时的操作:

@Override
protected void onDraw(Canvas canvas) {
    // modify paint shader according to mShowWave state
    if(mShowWave&& mWaveShader!= null) {
        // first call after mShowWave, assign it to our paint
        if(mViewPaint.getShader() ==null) {
            mViewPaint.setShader(mWaveShader);
        }

        // sacle shader according to mWaveLengthRatio and mAmplitudeRatio
        // this decides the size(mWaveLengthRatio for width, mAmplitudeRatio for height) of waves
        mShaderMatrix.setScale(
                mWaveLengthRatio/ DEFAULT_WAVE_LENGTH_RATIO,
                mAmplitudeRatio/ DEFAULT_AMPLITUDE_RATIO,
                0,
                mDefaultWaterLevel);
        // translate shader according to mWaveShiftRatio and mWaterLevelRatio
        // this decides the start position(mWaveShiftRatio for x, mWaterLevelRatio for y) of waves
        mShaderMatrix.postTranslate(
                mWaveShiftRatio* getWidth(),
                (DEFAULT_WATER_LEVEL_RATIO- mWaterLevelRatio) * getHeight());

        // assign matrix to invalidate the shader
        mWaveShader.setLocalMatrix(mShaderMatrix);

        float borderWidth =mBorderPaint ==null ?0f :mBorderPaint.getStrokeWidth();

        if (borderWidth >0) {
            canvas.drawRect(
                    borderWidth / 2f,
                    borderWidth /2f,
                    getWidth() - borderWidth /2f -0.5f,
                    getHeight() - borderWidth /2f -0.5f,
                    mBorderPaint);
        }
        canvas.drawRect(borderWidth,borderWidth,getWidth() - borderWidth,
                getHeight() - borderWidth,mViewPaint);

    }else {
        mViewPaint.setShader(null);
    }
}

 

 

布局改变时重新绘制波浪图形:

@Override
protected void onSizeChanged(intw, inth, intoldw, intoldh) {
    super.onSizeChanged(w,h,oldw,oldh);

    createShader();
}

就这样简单的完成了

0 0
原创粉丝点击