自定义View控件画圆,拖动圆

自定义控件:

     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;
    }
}

xx1


666

                                       圆形图片

/*******************************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;
    }
}






    


  








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值