自定义VIEW,可拖动的控件

本文介绍了一个自定义的Android View组件,该组件显示一个带十字标记的圆形,并支持通过鼠标拖动进行位置调整。文章详细展示了如何通过创建MyView类并覆盖onMeasure和onDraw方法来实现这一功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个自定义view是显示的一个中间是十字的圆圈,可以用鼠标点击之后拖动,非常简单,也可以自己设置样式。

1:创建一个Myview类,继承View,实现里面的三个构造器,里面写所有的关于控件的操作,包括拖动和调整控件的显示图像:

package text.bwie.com.zidingyiview;

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.util.Log;
import android.view.MotionEvent;
import android.view.View;

/**
 * 类描述:
 * 姓名 :刘希鑫
 */

public class MyView extends View{
    //用三个构造器,一个参数的,两个参数的,和三个参数的
    private int radius=200;
    private float x;
    private float y;

   //第一个构造器,一个参数要写两个,给个null
    public MyView(Context context) {
        super(context,null);
    }
    //两个参数的增加个0
    public MyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs,0);
    }
    public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    /**
     * 测量宽高
     * @param widthMeasureSpec  宽度和模式的合体值
     * @param heightMeasureSpec 高度和模式的合体值
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //        MeasureSpec.AT_MOST; //不确定的值 wrap_content
        //        MeasureSpec.EXACTLY;//固定值
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);

        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        Log.e("onMeasure", "onMeasure: x-"+widthMode+"/"+widthSize);
        Log.e("onMeasure", "onMeasure: y-"+heightMode+"/"+heightSize);

         if (widthMode==MeasureSpec.AT_MOST){
           widthMode=2*radius;
         }else if (widthMode==MeasureSpec.EXACTLY){
             if (widthSize<2*radius){
                 radius=widthSize/2;
             }
         }
         if (heightMode==MeasureSpec.AT_MOST){
             heightMode=2*radius;
         }
          //最后的属性会报错,但是不影响运行的话就不用管,就像是版本号不同一样233
        int width = MeasureSpec.makeMeasureSpec(widthSize, widthMode);
        int height = MeasureSpec.makeMeasureSpec(heightSize,heightMode);
        x = widthSize/2;
        y = heightSize/2;
        setMeasuredDimension(width,height);

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
       switch (event.getAction()){
           case MotionEvent.ACTION_MOVE:
               x=event.getX();
               y=event.getY();
             postInvalidate();
               break;
       }

        return true;
    }

    /**
     * 绘制内容
     * @param canvas 画布
     */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint=new Paint();
        paint.setColor(Color.BLUE);
        /**
         *  Paint.Style.FILL:填充内部
         *  Paint.Style.FILL_AND_STROKE  :填充内部和描边
         *  Paint.Style.STROKE  :描边
         */
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(5);
        canvas.drawCircle(x,y,radius,paint);

        paint.setColor(Color.GRAY);
        canvas.drawLine(x-radius,y,x+radius,y,paint);
        canvas.drawLine(x,y-radius,x,y+radius,paint);

//        paint.setColor(Color.RED);
//        paint.setTextAlign(Paint.Align.CENTER);
//        Rect bounds = new Rect();
//        String text = "1506B";
//        paint.getTextBounds(text, 0, text.length(), bounds);
//        paint.setTextSize(50);
//        paint.setStrokeWidth(2);
//        canvas.drawText(text,x,y,paint);
    }
}

2:然后只要在主activity布局中调用就可以了,控件就是你自己定义的这个类名字

<text.bwie.com.zidingyiview.MyView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值