一个动态波浪纹Android界面
阅读原文时间:2023年07月09日阅读:1

IndexActivity.java

package com.example.rubikrobot;

import androidx.appcompat.app.AppCompatActivity;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.view.Window;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.Button;
import android.widget.ImageView;

import java.util.ArrayList;

public class IndexActivity extends AppCompatActivity {
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_index);
final RippleBackground rippleBackground=findViewById(R.id.content);
final Handler handler=new Handler(Looper.myLooper());
//foundDevice=(ImageView)findViewById(R.id.foundDevice);
button=findViewById(R.id.centerImage);
rippleBackground.startRippleAnimation();
Intent intent=new Intent();
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
intent.setClass(IndexActivity.this,MainActivity.class);
startActivity(intent);
}
});

}  

}

RippleBackground.java

package com.example.rubikrobot;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.RelativeLayout;

import java.util.ArrayList;

public class RippleBackground extends RelativeLayout{

private static final int DEFAULT\_RIPPLE\_COUNT=6;  
private static final int DEFAULT\_DURATION\_TIME=3000;  
private static final float DEFAULT\_SCALE=6.0f;  
private static final int DEFAULT\_FILL\_TYPE=0;

private int rippleColor;  
private float rippleStrokeWidth;  
private float rippleRadius;  
private int rippleDurationTime;  
private int rippleAmount;  
private int rippleDelay;  
private float rippleScale;  
private int rippleType;  
private Paint paint;  
private boolean animationRunning=false;  
private AnimatorSet animatorSet;  
private ArrayList<Animator> animatorList;  
private LayoutParams rippleParams;  
private ArrayList<RippleView> rippleViewList=new ArrayList<RippleView>();

public RippleBackground(Context context) {  
    super(context);  
}

public RippleBackground(Context context, AttributeSet attrs) {  
    super(context, attrs);  
    init(context, attrs);  
}

public RippleBackground(Context context, AttributeSet attrs, int defStyleAttr) {  
    super(context, attrs, defStyleAttr);  
    init(context, attrs);  
}

private void init(final Context context, final AttributeSet attrs) {  
    if (isInEditMode())  
        return;

    if (null == attrs) {  
        throw new IllegalArgumentException("Attributes should be provided to this view,");  
    }

    final TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RippleBackground);  
    rippleColor=typedArray.getColor(R.styleable.RippleBackground\_rb\_color, getResources().getColor(R.color.rippelColor));  
    rippleStrokeWidth=typedArray.getDimension(R.styleable.RippleBackground\_rb\_strokeWidth, getResources().getDimension(R.dimen.rippleStrokeWidth));  
    rippleRadius=typedArray.getDimension(R.styleable.RippleBackground\_rb\_radius,getResources().getDimension(R.dimen.rippleRadius));  
    rippleDurationTime=typedArray.getInt(R.styleable.RippleBackground\_rb\_duration,DEFAULT\_DURATION\_TIME);  
    rippleAmount=typedArray.getInt(R.styleable.RippleBackground\_rb\_rippleAmount,DEFAULT\_RIPPLE\_COUNT);  
    rippleScale=typedArray.getFloat(R.styleable.RippleBackground\_rb\_scale,DEFAULT\_SCALE);  
    rippleType=typedArray.getInt(R.styleable.RippleBackground\_rb\_type,DEFAULT\_FILL\_TYPE);  
    typedArray.recycle();

    rippleDelay=rippleDurationTime/rippleAmount;

    paint = new Paint();  
    paint.setAntiAlias(true);  
    if(rippleType==DEFAULT\_FILL\_TYPE){  
        rippleStrokeWidth=0;  
        paint.setStyle(Paint.Style.FILL);  
    }else  
        paint.setStyle(Paint.Style.STROKE);  
    paint.setColor(rippleColor);

    rippleParams=new LayoutParams((int)(2\*(rippleRadius+rippleStrokeWidth)),(int)(2\*(rippleRadius+rippleStrokeWidth)));  
    rippleParams.addRule(CENTER\_IN\_PARENT, TRUE);

    animatorSet = new AnimatorSet();  
    animatorSet.setInterpolator(new AccelerateDecelerateInterpolator());  
    animatorList=new ArrayList<Animator>();

    for(int i=0;i<rippleAmount;i++){  
        RippleView rippleView=new RippleView(getContext());  
        addView(rippleView,rippleParams);  
        rippleViewList.add(rippleView);  
         final ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(rippleView, "ScaleX", 1.0f, rippleScale);  
        scaleXAnimator.setRepeatCount(ObjectAnimator.INFINITE);  
        scaleXAnimator.setRepeatMode(ObjectAnimator.RESTART);  
        scaleXAnimator.setStartDelay(i \* rippleDelay);  
        scaleXAnimator.setDuration(rippleDurationTime);  
        animatorList.add(scaleXAnimator);  
        final ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(rippleView, "ScaleY", 1.0f, rippleScale);  
        scaleYAnimator.setRepeatCount(ObjectAnimator.INFINITE);  
        scaleYAnimator.setRepeatMode(ObjectAnimator.RESTART);  
        scaleYAnimator.setStartDelay(i \* rippleDelay);  
        scaleYAnimator.setDuration(rippleDurationTime);  
        animatorList.add(scaleYAnimator);  
        final ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(rippleView, "Alpha", 1.0f, 0f);  
        alphaAnimator.setRepeatCount(ObjectAnimator.INFINITE);  
        alphaAnimator.setRepeatMode(ObjectAnimator.RESTART);  
        alphaAnimator.setStartDelay(i \* rippleDelay);  
        alphaAnimator.setDuration(rippleDurationTime);  
        animatorList.add(alphaAnimator);  
    }

    animatorSet.playTogether(animatorList);  
}

private class RippleView extends View{

    public RippleView(Context context) {  
        super(context);  
        this.setVisibility(View.INVISIBLE);  
    }

    @Override  
    protected void onDraw(Canvas canvas) {  
        int radius=(Math.min(getWidth(),getHeight()))/2;  
        canvas.drawCircle(radius,radius,radius-rippleStrokeWidth,paint);  
    }  
}

public void startRippleAnimation(){  
    if(!isRippleAnimationRunning()){  
        for(RippleView rippleView:rippleViewList){  
            rippleView.setVisibility(VISIBLE);  
        }  
        animatorSet.start();  
        animationRunning=true;  
    }  
}

public void stopRippleAnimation(){  
    if(isRippleAnimationRunning()){  
        animatorSet.end();  
        animationRunning=false;  
    }  
}

public boolean isRippleAnimationRunning(){  
    return animationRunning;  
}  

}

layout