自定义View实现点击事件

简介: 自定义View实现点击事件

1.自定义View的实现


继承自View 重写 onDraw方法

public class MyLine extends View {
    Paint mPaint;
    int startX;
    int startY;
    int endX;
    int endY;
    public static Point mPoint1;
    public static Point mPoint2;
    public MyLine(Context context) {
        super(context);
        initPaint();
    }
    public MyLine(Context context,
            @Nullable AttributeSet attrs) {
        super(context, attrs);
        initPaint();
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyLine);
        startX = ta.getInteger(R.styleable.MyLine_startX,100);
        startY = ta.getInteger(R.styleable.MyLine_startY, 100);
        endX = ta.getInteger(R.styleable.MyLine_endX,100);
        endY = ta.getInteger(R.styleable.MyLine_endY, 100);
        mPoint1 = new Point(startX,startY);
        mPoint2 = new Point(endX,endY);
    }
    public static Point getPoint1() {
        return mPoint1;
    }
    public static Point getPoint2() {
        return mPoint2;
    }
    public MyLine(Context context,
            @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initPaint();
    }
    public MyLine(Context context,
            @Nullable AttributeSet attrs, int defStyleAttr,
            int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initPaint();
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawLine(startX,startY,endX,endY,mPaint);
    }
    public void initPaint(){
        mPaint = new Paint();
        mPaint.setColor(Color.BLUE);
        mPaint.setAntiAlias(true);
        mPaint.setStrokeWidth(10);
    }
}

2.自定义View 自定义属性


在values文件夹下创建attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyPoint">
        <attr name="X" format="integer"/>
        <attr name="Y" format="integer"/>
    </declare-styleable>
    <declare-styleable name="MyLine">
        <attr name="startX" format="integer"/>
        <attr name="endX" format="integer"/>
        <attr name="startY" format="integer"/>
        <attr name="endY" format="integer"/>
    </declare-styleable>
</resources>

获取属性

TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyLine);
        startX = ta.getInteger(R.styleable.MyLine_startX,100);
        startY = ta.getInteger(R.styleable.MyLine_startY, 100);
        endX = ta.getInteger(R.styleable.MyLine_endX,100);
        endY = ta.getInteger(R.styleable.MyLine_endY, 100);

3.添加点击事件


在自定义view的类里添加触摸事件和点击事件的接口

   

@Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_UP:
                if (x + getLeft() < getRight() && y + getTop() < getBottom()) {
                    mPoint = new Point(x,y);
                    mViewClick.onClick(x,y,mOnViewClick);
                }
                break;
        }
        return true;
    }
    public void setOnViewClick(onViewClick click) {
        this.mViewClick = click;
    }
    public interface onViewClick {
        void onClick(int scrollX, int scrollY,onViewClick onViewClick);
    }
    onViewClick mOnViewClick = new onViewClick() {
        @Override
        public void onClick(int scrollX, int scrollY, onViewClick onViewClick) {
           sX = scrollX;
           sY = scrollY;
           invalidate();// 重绘 会重新调用onDraw方法
        }
    };
mMyPoint = findViewById(R.id.point);
mMyPoint.setOnViewClick(mMyPoint.mOnViewClick);

4.绘制虚线


mPaint.setPathEffect(new DashPathEffect(new float[] {30, 5}, 0)); 其中30 表示实线的长度 5代表空白的长度


5.已知直线和直线外一点,获取垂足坐标


//
//    private Point getFoot(Point p1,Point p2,Point p3){
//        Point foot=new Point();
//
//        float dx=p1.x-p2.x;
//        float dy=p1.y-p2.y;
//        Log.e("TAG",dx+"     "+dy);
//        float u=(p3.x-p1.x)*dx+(p3.y-p1.y)*dy;
//        u/=dx*dx+dy*dy;
//
//        foot.x=(int)(p1.x+u*dx);
//        foot.y=(int)(p1.y+u*dy);
//
//        float d=Math.abs((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
//        float d1=Math.abs((p1.x-foot.x)*(p1.x-foot.x)+(p1.y-foot.y)*(p1.y-foot.y));
//        float d2=Math.abs((p2.x-foot.x)*(p2.x-foot.x)+(p2.y-foot.y)*(p2.y-foot.y));
//
//        if(d1>d||d2>d){
//            if (d1>d2)  return p2;
//            else return p1;
//        }
//
//        return foot;
//    }
    private Point getFoot(Point p1,Point p2,Point p3){
        Point foot=new Point();
        float dx=p1.x-p2.x;
        float dy=p1.y-p2.y;
        float u=(p3.x-p1.x)*dx+(p3.y-p1.y)*dy;
        u/=dx*dx+dy*dy;
        foot.x=(int)(p1.x+u*dx);
        foot.y=(int)(p1.y+u*dy);
        return foot;
    }


目录
相关文章
|
监控 安全 Linux
【Elasticsearch专栏 14】深入探索:Elasticsearch使用Logstash的日期过滤器删除旧数据
使用Logstash的日期过滤器可以有效删除Elasticsearch中的旧数据,释放存储空间并提高集群性能。通过配置Logstash,可以指定索引模式、筛选时间戳早于特定阈值的文档,并在输出阶段删除这些旧数据。执行配置时,需确保Logstash与Elasticsearch连接正常,并监控日志以确保操作安全。定期执行此操作可确保旧数据不会过多积累。总之,Logstash的日期过滤器提供了一种简单而高效的方法,帮助管理和优化Elasticsearch中的数据。
447 0
|
数据可视化 JavaScript 前端开发
Turf.js介绍
Turf.js介绍
1928 0
|
人工智能 Java 对象存储
Java获取阿里云图片临时URL与图片文件转换Base64编码方法
在使用阿里云人工智能产品服务时,有部分服务需要上传的参数中包含文件URL,当我们没有开通OSS服务时,可以使用临时URL服务、或部分服务支持Base64编码格式,此文章为生成临时URL-JavaSDK方案与图片文件转换Base64编码方案。
2557 0
|
前端开发
前端引入字体文件
文章介绍了如何在前端项目中引入字体文件,并展示了具体的HTML和CSS代码示例,包括如何使用`@font-face`规则来定义字体和在页面中应用自定义字体。
730 1
前端引入字体文件
|
存储 Java 数据安全/隐私保护
Java技术栈揭秘:Base64加密和解密文件的实战案例
以上就是我们今天关于Java实现Base64编码和解码的实战案例介绍。希望能对你有所帮助。还有更多知识等待你去探索和学习,让我们一同努力,继续前行!
713 5
|
Java Android开发 Spring
Android Spingboot 实现SSE通信案例
【7月更文挑战第14天】以下是使用Android和Spring Boot实现SSE(Server-Sent Events)通信的案例摘要: 在`MainActivity`中: - 初始化界面元素并设置按钮点击事件。 - `startSseRequest`方法创建`WebClient`对象,设置请求头,发送请求,并处理响应和错误。 请确保将`your-server-url`替换为实际的服务器地址。
819 14
|
机器学习/深度学习 Unix 开发者
python的环境管理工具有哪些
python的环境管理工具有哪些
562 0
|
安全 应用服务中间件 nginx
Nginx访问403
Nginx访问403
1821 3
|
API
Camera2预览方向、拍照方向设置
Camera2预览方向、拍照方向设置
1458 2
|
Java
Java中break和continue语句的区别
Java中break和continue语句的区别
521 0