水波紋(自定義View)
阿新 • • 發佈:2019-01-10
自定義控制元件:
public class WaveView extends View { private static final String TAG = "WaveView"; private float fai = 0; private Paint paint1; private Paint paint2; private Path path1; private Path path2; 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; } private 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.setStyle(Paint.Style.FILL); paint2.setAntiAlias(true); 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()); // 從最左側開始,畫到最右側,每20px畫一條線 for (int x = 0; x <= getMeasuredWidth(); x += 20) { // float y = Asin(Ωx+φ)+k 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); } // Log.i(TAG, "onDraw: (" + x + ", " + y + ")"); 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 static final String TAG = "MainActivity"; 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) { // // Log.i(TAG, "onChanged: y=" + y); RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) imgCursor.getLayoutParams(); layoutParams.setMargins(0, 0, 0, (int) y); imgCursor.setLayoutParams(layoutParams); } }; wv.setOnWaveChangeListener(listener); // 會呼叫onMeasure和onLayout方法 // wv.requestLayout(); } }
xml檔案:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <RelativeLayout android:layout_width="match_parent" android:layout_height="200px" android:background="#F4CFFA" > <zidingyi.bawie.com.rikao1007.WaveView android:id="@+id/wv" android:layout_width="wrap_content" android:layout_height="10dp" android:layout_alignParentBottom="true" /> <ImageView android:id="@+id/img_cursor" android:layout_width="100dp" android:layout_height="100dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:src="@drawable/timg" /> </RelativeLayout> </LinearLayout>
實現效果: