布局:
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout 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" tools:context="com.example.day_0330_view.MainActivity"> <com.example.day_0330_view.CircleView android:layout_width="wrap_content" android:layout_height="wrap_content" />
</android.support.constraint.ConstraintLayout>
编写自定义View
import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; public class CircleView extends View{ int x = 100; int y = 100; //当我们new这个类时就会调用这个方法 public CircleView(Context context) { super(context); } //当我们在布局文件里去引用这个类的时候 public CircleView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } //当我们在布局文件里去用这个类时就会调用 defStyleAttr可以设置他的样式 public CircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = new Paint(); //设置颜色 paint.setColor(Color.RED); /** * 画笔样式分三种: 1.Paint.Style.STROKE:描边 2.Paint.Style.FILL_AND_STROKE:描边并填充 * 3.Paint.Style.FILL:填充 */ paint.setStyle(Paint.Style.FILL); //设置描边的宽度 // paint.setStrokeWidth(50); //设置抗锯齿 paint.setAntiAlias(true); /** * 第一个参数是x轴的距离 * 第二个参数是y轴的距离 * 第三个参数是圆的半径 * 第四个参数是画笔 */ canvas.drawCircle(x,y,100,paint); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: x = (int) event.getX(); y = (int) event.getY(); break; case MotionEvent.ACTION_MOVE: x = (int) event.getX(); y = (int) event.getY(); break; case MotionEvent.ACTION_UP: x = (int) event.getX(); y = (int) event.getY(); break; } //重新绘制, 只要调用此方法,就会调用onDraw() // invalidate(); 只能在主线程里面去调用,不能在子线程里面去调用 //既能在主线程里面去调用,也能在子线程里面去调用 postInvalidate(); //事件自己消费掉 return true; } }