自定义控件:
1.自绘控件(完全自定义控件)
2.组合式自定义控件
3.继承式自定义控件
View 是所有控件的超类
自绘式自定义控件实现步骤:
1.类继承view(从一个普通的类变成一个控件了)
2.覆写他必须要覆写的三个方法 三个构造方法(第四个不用实现)
//因为都是构造方法 重载 只会调用一个
//这三个方法是让你做初始化的业务逻辑
//代码中使用自定义控件(),自动回调此方法
//只有使用动态式使用 即创建这个对象时才会调用此方法
public MyView(Context context)
//在xml中使用此控件,自动回调此方法 包名+类名 可以按住Ctrl 看它能不能调到指定的类啥的 只有使用xml包名.类名时才会调用
public MyView_Hy(Context context, @Nullable AttributeSet attrs)
//XML布局中使用此自定义控件,且带有样式时自动回调
public MyView(Context context, AttributeSet attrs, int defStyleAttr)
//使用触摸事件来实现小球的拖动
//理解:主要是根据圆心坐标(x,y)的变化来确定圆的新位置
首先要返回true ,事件分发机制 返回true表示这个事件自己处理 不返给父控件
ActionMove时坐标的变化 以此改变圆心的坐标
3.具体类代码
public class MyView extends View { private int x; private int y; private Paint paint; private int radius=100; //---------------------------------分割线-------------------------- //因为都是构造方法 重载 只会调用一个 //这三个方法是让你做初始化的业务逻辑 //代码中使用自定义控件(),自动回调此方法 //只有使用动态式使用 即创建这个对象时才会调用此方法 public MyView(Context context) { super(context); } // 在xml中使用此控件,自动回调此方法 包名+类名 只有使用xml包名.类名时才会调用 public MyView(Context context, AttributeSet attrs) { super(context, attrs); //创建一个画笔 paint = new Paint(); //设置颜色 paint.setColor(Color.GREEN); //设置透明度 paint.setAlpha(255); //设置画笔为空心 默认是有填充的paint.setStyle(Paint.Style.FILL); paint.setStyle(Paint.Style.STROKE); //设置画笔线宽 paint.setStrokeWidth(2); //设置抗锯齿 paint.setAntiAlias(true); } // XML布局中使用此自定义控件,且带有样式时自动回调 public MyView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } //---------------------------------分割线-------------------------- @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //根据参数 创建参数 canvas.drawCircle(x,y, radius,paint); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //获取当前控件的宽和高 int width = this.getWidth(); int height = this.getHeight(); //获取屏幕的正中心点 就是屏幕宽高1/2的坐标 //注意这里的控件由于是match match 属性所以这样可以得到屏幕中心点 x = width / 2; y = height / 2; //这个方法也可以得到 屏幕的正中心点 ( 得到模拟器(真机)的 屏幕宽高) // WindowManager manager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); // int width1 = manager.getDefaultDisplay().getWidth(); // int height1 = manager.getDefaultDisplay().getHeight(); // x=width1/2; // y=height1/2; } //使用触摸事件来实现小球的拖动 //理解:主要是根据圆心坐标(x,y)的变化来确定圆的新位置 @Override public boolean onTouchEvent(MotionEvent event) { switch(event.getAction()){ case MotionEvent.ACTION_DOWN://按下 int xDOWN = (int) event.getX(); int yDOWN = (int) event.getY(); boolean onBall = isOnBall(xDOWN, yDOWN); if(onBall){ Toast.makeText(getContext(),"按在圆上了",Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(getContext(),"不在圆上",Toast.LENGTH_SHORT).show(); } break; case MotionEvent.ACTION_UP://松开 break; case MotionEvent.ACTION_MOVE://移动 //也可以加个判断 当他为True时 在进行这里的代码操作 int xMove = (int) event.getX(); int yMove = (int) event.getY(); x=xMove; y=yMove; //刷新当前视图 invalidate(); break; case MotionEvent.ACTION_CANCEL://取消 break; default: break; } return true;//返回true表示这个事件自己处理 } private boolean isOnBall(int xDOWN, int yDOWN) { //先用勾股定理开方 得到 按下的坐标到圆心的距离 double sqrt = Math.sqrt((xDOWN - x) * (xDOWN - x) + (yDOWN - y) * (yDOWN - y)); if(sqrt<radius){ return true; } return false; } }
圆形图片
/*******************************XML直接引用******************************************/
public class RoundImageView extends ImageView {
public RoundImageView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public RoundImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RoundImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap b = ((BitmapDrawable) drawable).getBitmap();
if (null == b) {
return;
}
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
int w = getWidth(), h = getHeight();
Bitmap roundBitmap = getCroppedBitmap(bitmap, w);
canvas.drawBitmap(roundBitmap, 0, 0, null);
}
public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
Bitmap sbmp;
if (bmp.getWidth() != radius || bmp.getHeight() != radius)
sbmp = Bitmap.createScaledBitmap(bmp, radius, radius, false);
else
sbmp = bmp;
Bitmap output = Bitmap.createBitmap(sbmp.getWidth(), sbmp.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xffa19774;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, sbmp.getWidth(), sbmp.getHeight());
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
//设置笔的颜色
paint.setColor(Color.parseColor("#BAB399"));
//画圆
canvas.drawCircle(sbmp.getWidth() / 2 + 0.5f,
sbmp.getHeight() / 2 + 0.5f, sbmp.getWidth() / 2 + 0.5f, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(sbmp, rect, rect, paint);
return output;
}
}