WaveView
package com.example.windows.waveview; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.DrawFilter; import android.graphics.Paint; import android.graphics.PaintFlagsDrawFilter; import android.graphics.Path; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.view.View; /** * Created by Windows on 2018/10/7. */ public class WaveView extends View{ private float fai = 0; private Path path1; private Path path2; private Paint paint1; private Paint paint2; private DrawFilter drawFilter; public WaveView(Context context) { this(context,null); } public WaveView(Context context, @Nullable AttributeSet attrs) { this(context, attrs,0); } public WaveView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } public interface onWaveChangeListener{ void onChanged(float y); } private onWaveChangeListener listener; public void setonWaveChangeListener(onWaveChangeListener listener) { this.listener = listener; } public void init(){ paint1 = new Paint(); paint1.setColor(Color.WHITE); paint1.setAntiAlias(true); paint1.setStyle(Paint.Style.FILL); paint1.setStrokeWidth(5); paint2 = new Paint(); paint2.setColor(Color.WHITE); paint2.setAntiAlias(true); paint2.setStyle(Paint.Style.FILL); paint2.setStrokeWidth(5); paint2.setAlpha(60); path1 = new Path(); path2 = new Path(); drawFilter = new PaintFlagsDrawFilter(0, Paint. FILTER_BITMAP_FLAG | Paint.ANTI_ALIAS_FLAG); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); double Ω = 2 * Math.PI /getMeasuredWidth(); canvas.setDrawFilter(drawFilter); fai -= 0.1f; int A = getMeasuredHeight() / 2; path1.reset(); path2.reset(); path1.moveTo(getLeft(),getBottom()); path2.moveTo(getLeft(),getBottom()); for (int x = 0; x <= getMeasuredWidth() ; x+=20) { float y1 = A * (float) Math.sin(Ω * x + fai) + A; float y2 = -A * (float) Math.sin(Ω * x + fai) + A; if (x > getMeasuredWidth()/2 - 10 && x < getMeasuredWidth()/2+10){ listener.onChanged(y2); } path1.lineTo(x,y1); path2.lineTo(x,y2); } path1.lineTo(getWidth(),getBottom()); path2.lineTo(getWidth(),getBottom()); canvas.drawPath(path1,paint1); canvas.drawPath(path2,paint2); postInvalidateDelayed(50); } }
MainActivity
public class MainActivity extends AppCompatActivity { private WaveView wv; private ImageView imgCursor; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); wv = findViewById(R.id.wv); imgCursor = findViewById(R.id.img_cursor); WaveView.onWaveChangeListener listener = new WaveView.onWaveChangeListener() { @Override public void onChanged(float y) { RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) imgCursor.getLayoutParams(); layoutParams.setMargins(0,0,0, (int) y); imgCursor.setLayoutParams(layoutParams); } }; wv.setonWaveChangeListener(listener); } }
activity_main .xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.windows.waveview.MainActivity"> <RelativeLayout android:layout_width="match_parent" android:layout_height="200px" android:background="#FF0000"> <com.example.windows.waveview.WaveView android:id="@+id/wv" android:layout_width="wrap_content" android:layout_height="40px" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true"/> <ImageView android:id="@+id/img_cursor" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/ic_launcher" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true"/> </RelativeLayout> </LinearLayout>