一、Xml布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#80000f"
tools:context="com.example.mickc.customviews.MainActivity">
<FrameLayout
android:layout_marginTop="200dp"
android:layout_width="match_parent"
android:background="#ff7403"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/image"
android:layout_gravity="center_horizontal"
android:src="@mipmap/ic_launcher"
/>
<com.example.mickc.customviews.WaveView
android:layout_marginTop="100dp"
android:layout_width="match_parent"
android:layout_height="15dp"
android:id="@+id/waveView"
/>
</FrameLayout>
</LinearLayout>
二、Activity中
public class MainActivity extends AppCompatActivity {
private ImageView image;
private WaveView waveView;
private FrameLayout.LayoutParams lp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
image = (ImageView) findViewById(R.id.image);
waveView = (WaveView) findViewById(R.id.waveView);
lp = new FrameLayout.LayoutParams(-2,-2);
lp.gravity=Gravity.CENTER;
waveView.setAnimations(new WaveView.Animations() {
@Override
public void getY(float y) {
lp.setMargins(0,-20,0, (int) (y+2));
image.setLayoutParams(lp);
}
});
}
}
三、工具类
public class WaveView extends View {
private Paint paint;
private Path path;
float A=8f;
float w;
float k=0f;
float f;
float y;
private Paint paint1;
private Path path1;
private float y1;
public WaveView(Context context) {
super(context);
initView();
}
public WaveView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initView();
}
public WaveView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
private void initView() {
//创建一个画笔
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.WHITE);
paint.setAntiAlias(true);//消除锯齿
paint.setStyle(Paint.Style.FILL);
path = new Path();
//创建一个画笔
paint1 = new Paint(Paint.ANTI_ALIAS_FLAG);
paint1.setColor(Color.WHITE);
paint1.setAntiAlias(true);//消除锯齿
paint1.setStyle(Paint.Style.FILL);
paint1.setAlpha(80);
path1 = new Path();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
path.reset();
path1.reset();
/**
* y=Asin(ωx+φ)+k
* A—振幅越大,波形在y轴上最大与最小值的差值越大
* ω—角速度, 控制正弦周期(单位角度内震动的次数)
* φ—初相,反映在坐标系上则为图像的左右移动。这里通过不断改变φ,达到波浪移动效果
* k—偏距,反映在坐标系上则为图像的上移或下移。
*/
path.moveTo(getLeft(),getBottom());
path1.moveTo(getLeft(),getBottom());
w= (float) (2*Math.PI/getWidth());
f-=0.1f;
for (int x = 0; x <=getWidth() ; x+=20) {
y= (float) (A*Math.sin(w*x+f));
y1 = (float) (A*Math.cos(w*x+f)+8);
path.lineTo(x,y);
path1.lineTo(x,y1);
animations.getY(y);
}
path.lineTo(getRight(),getBottom());
path1.lineTo(getRight(),getBottom());
canvas.drawPath(path,paint);
canvas.drawPath(path1,paint1);
postInvalidateDelayed(20);
}
public void setAnimations(Animations animations) {
this.animations = animations;
}
private Animations animations;
public interface Animations{
void getY(float y);
}
}