Android Canvas绘制带箭头的直线

先看下效果图:

在这里插入图片描述

下面我们直接看代码

我自定义了一个View,代码如下:

package com.davis.drawtrangle;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;import java.util.ArrayList;
import java.util.List;public class DrawView extends View {private List<PointBean> pointLists = new ArrayList<PointBean>();private PointBean pointBean = new PointBean(-1, -1, -1, -1);private static int height = 30;private static int bottom = 10;private Paint paint = new Paint(){{setColor(Color.RED);setAntiAlias(true);setStrokeWidth(4.0f);}};public DrawView(Context context) {super(context);}public DrawView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);}public DrawView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}public void clear(){if(pointBean != null){pointBean.setStartX(-1);pointBean.setStartY(-1);pointBean.setEndX(-1);pointBean.setEndY(-1);}if(pointLists != null && pointLists.size() > 0){pointLists.clear();}invalidate();}@Overrideprotected void onDraw(Canvas canvas) {//super.onDraw(canvas);if(pointLists != null && pointLists.size() > 0){for(int i=0;i<pointLists.size();i++){PointBean pb = pointLists.get(i);canvas.drawLine(pb.getStartX(), pb.getStartY(), pb.getEndX(), pb.getEndY(), paint);drawTrangle(canvas, paint, pb.getStartX(), pb.getStartY(), pb.getEndX(), pb.getEndY(), height, bottom);}}if(pointBean != null && pointBean.getStartX() != -1&& pointBean.getStartY() != -1 && pointBean.getEndX() != -1&& pointBean.getEndY() != -1){canvas.drawLine(pointBean.getStartX(), pointBean.getStartY(), pointBean.getEndX(), pointBean.getEndY(), paint);drawTrangle(canvas, paint, pointBean.getStartX(), pointBean.getStartY(), pointBean.getEndX(), pointBean.getEndY(), height, bottom);}}/*** 绘制三角* @param canvas* @param fromX* @param fromY* @param toX* @param toY* @param height* @param bottom*/private void drawTrangle(Canvas canvas, Paint paintLine, float fromX, float fromY, float toX, float toY, int height, int bottom){try{float juli = (float) Math.sqrt((toX - fromX) * (toX - fromX)+ (toY - fromY) * (toY - fromY));// 获取线段距离float juliX = toX - fromX;// 有正负,不要取绝对值float juliY = toY - fromY;// 有正负,不要取绝对值float dianX = toX - (height / juli * juliX);float dianY = toY - (height / juli * juliY);float dian2X = fromX + (height / juli * juliX);float dian2Y = fromY + (height / juli * juliY);//终点的箭头Path path = new Path();path.moveTo(toX, toY);// 此点为三边形的起点path.lineTo(dianX + (bottom / juli * juliY), dianY- (bottom / juli * juliX));path.lineTo(dianX - (bottom / juli * juliY), dianY+ (bottom / juli * juliX));path.close(); // 使这些点构成封闭的三边形canvas.drawPath(path, paintLine);}catch (Exception ex){ex.printStackTrace();}}@Overridepublic boolean onTouchEvent(MotionEvent event) {int action = event.getAction();switch (action){case MotionEvent.ACTION_DOWN:onActionDown(event);break;case MotionEvent.ACTION_MOVE:onActionMove(event);break;case MotionEvent.ACTION_UP:onActionUp(event);break;}return true;//return super.onTouchEvent(event);}private void onActionDown(MotionEvent event){try {if(pointBean == null){pointBean = new PointBean(-1, -1, -1, -1);}pointBean.setStartX(event.getX());pointBean.setStartY(event.getY());}catch (Exception ex){ex.printStackTrace();}invalidate();}private void onActionMove(MotionEvent event){try{if(pointBean != null){pointBean.setEndX(event.getX());pointBean.setEndY(event.getY());}}catch (Exception ex){ex.printStackTrace();}invalidate();}private void onActionUp(MotionEvent event){try {if(pointBean != null){pointBean.setEndX(event.getX());pointBean.setEndY(event.getY());PointBean pb = new PointBean();pb.setStartX(pointBean.getStartX());pb.setStartY(pointBean.getStartY());pb.setEndX(pointBean.getEndX());pb.setEndY(pointBean.getEndY());pointLists.add(pb);pointBean.setStartX(-1);pointBean.setStartY(-1);pointBean.setEndX(-1);pointBean.setEndY(-1);}}catch (Exception ex){ex.printStackTrace();}invalidate();}}

其中关键绘制箭头的是 drawTrangle() 这个方法。

完整的代码已上传到github上:Canvas绘制带箭头的直线

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/446821.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用named_mutex实现读写锁,实现进程之间读共享写独占

代码 代码的名称是read_write_mutex.h这个代码可用&#xff0c;但是未优化&#xff0c;还存在冗余的代码如果涉及到进程挂掉了&#xff0c;造成进程堵塞&#xff0c;如何解决&#xff1f;还未涉及 //#ifndef BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP #define BOOST_THREAD_PTHR…

Android Activity之间传递类对象

一、简介 开发过程中&#xff0c;Activity之间传递数据是必不可少的&#xff0c;Android中使用Intent和Bundle作为数据载体&#xff0c;在Activity之间传递&#xff0c;对于基础数据类型&#xff0c;Bundle已经提供了相关的put、set方法&#xff0c;而作为自定义的类型则需要有…

C++3个汉诺塔递归问题

3个汉诺塔问题A—>C 移动次数2^n-1 hannoni(int n,char a,char b,char c)把n个盘子借助b,从a移动到cmove(int n,char a,char c)把第n个盘子,从a移动到c #include<iostream> #include<cmath> using namespace std; //汉诺塔问题A--->C //2^n-1次移动次数 …

clion编译器解决undefined reference to symbol ‘shm_open@@GLIBC_2.2.5‘

修改CMakelists文件 cmake_minimum_required(VERSION 3.17) project(mutex_learn)set(CMAKE_CXX_STANDARD 14)set(BOOST_ROOT "/usr/local/include/boost") #添加头文件搜索路径 include_directories(/usr/local/include) #添加库文件搜索路径 link_directories(/us…

Android 拦截或屏蔽返回键

在Android开发中我们常常会遇到需要拦截或屏蔽返回键的需求&#xff0c;对拦截后的返回键进行特殊操作。 监听返回键有两种方式 1、重写OnBackPressed方法 Overridepublic void onBackPressed() {// 完全由自己控制返回键逻辑&#xff0c;系统不再控制&#xff0c;但是有个前…

C++递归斐波那契数列

第一种 //斐波那契数列 // 0 1 1 … //从第1个开始 代码 #include<iostream> #include<cmath> using namespace std; //斐波那契数列 // 0 1 1 ... //从第1个开始 int f(int n) {int m; if(n1)return 0;if(n2)return 1;elsemf(n-1)f(n-2);return m;} int mai…

Android onActivityResult中requestCode与resultCode区别

想要了解requestCode与resultCode的区别&#xff0c;我们需要先了解以下三个方法的用法&#xff1a; startActivityForResult(Intent intent, Int requestCode) setResut(int resultCode, Intent intent) onActivityResult(int requestCode, int resultCode, Intent intent) …

使用named_mutex和named_condition配合实现读写锁

代码 代码的名称是read_write_mutex.h初步优化如果涉及到进程挂掉了&#xff0c;造成进程堵塞&#xff0c;如何解决&#xff1f;还未涉及 #include <boost/interprocess/sync/named_condition.hpp> #include <boost/interprocess/sync/named_mutex.hpp>namespace …

C++的输入与输出

输入与输出 输入:从外部输入设备(键盘)向计算机输入数据 输出:从计算机向外部输出设备(显示屏)输出数据 C使用流对象实现 使用流对象cin与cout,将标准输入输出流库的头文件iostream包含到源文件 #include<iostream>//标准输入输出库 using namespace std;//使用标准命…

Android 动态计算ListView的高度

目录一、简介二、效果图三、代码实现一、简介 在Android开发的过程中有的时候我们需要手动计算ListView的高度&#xff0c;比如说&#xff0c;ScrollView中嵌套ListView的时候&#xff0c;我们就需要手动精确计算ListView的高度了。 如果ListView的Item高度是固定的话还好计算…

DjangoRestFramework(drf实现五个接口)

安装&#xff1a;pip install djangorestframework 在使用drf之前&#xff0c;先 使用原生Django实现5个接口 models.py from django.db import modelsclass Book(models.Model):namemodels.CharField(max_length53)pricemodels.IntegerField() views.py from app01 impor…

linux使用共享内存进行进程通信

一、什么是共享内存 共享内存就是允许两个不相关的进程访问同一个逻辑内存。共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常为同一段物理内存。使用共享内存进行通信的进程都需要同一段共享内存连接到它们自己的地址空间…

安卓TextView文本框与自定义边框

常用属性 自定义边框 基本使用 <?xml version"1.0" encoding"utf-8"?> <shape xmlns:android"http://schemas.android.com/apk/res/android"android:shape"rectangle矩形/ring圆环/oval椭圆/line直线"当为圆环时android:s…

Android RecyclerView实现九宫格效果

RecyclerView更加优化的复用机制和方便实现UI效果&#xff0c;几乎替代Listview和GridView的使用。但是分割线的实现&#xff0c;需要自己继承ItemDecoration来绘制。 完整代码已上传至Github&#xff1a;RecyclerView实现九宫格效果 效果图 item的布局文件 <?xml versi…

如何读取指针指向的地址空间呢?

方法 使用%p 接收指针返回的地址空间 代码 #include <stdio.h> #include <stdlib.h>int main() {int a 100;int *a_p &a;printf("%p\n",&a);//输出&#xff1a;002AF744 输出的是a变量的地址printf("%p\n",a_p);//输出&#xff1…

科学究研明表,汉字序顺并不一定影阅响读

有个很有意思的现象&#xff1a; 不信你就来试试 中文打乱小工具 github地址&#xff1a;在线打乱文字顺序

安卓EditText

常用属性 android:textAllCaps"false"去除大写状态 inputType 常用 textpassword密码 number数字 phone拨号键盘 设置光标位置 editText.setSelection(2);从1开始 editText.setSelection(1,3);从1开始,1–3中间部分,一个范围

完善博文 共享内存一写多读无锁实现的代码逻辑部分

使用共享内存(内存映射)实现发布订阅模式 多进程实现PubSub发布订阅模式&#xff0c;从而实现进程间的通信。通信方式可以是TCP/UDP&#xff0c;管道Pipe/消息队列&#xff0c;共享内存shared memory等等。其中TCP/UDP的方式是可以用作局域网以及跨平台的通信&#xff0c;Pipe…

想对你说的话,就在这里!

甜(Tu)言(Wei)蜜(Qing)语(Hua)最近在github上看到了一个朋友开发的 土味情话在线生成器 &#xff0c;感觉还不错&#xff0c;在这里推荐一下。 github地址&#xff1a;在线生成土味情话

linux读写文件 简单版

代码 //write void write_file(const std::string file_name){FILE *fp nullptr;fp fopen(file_name.c_str(),"w");fprintf(fp,"This is testing for mutex\n");fclose(fp); } //read void read_file(const std::string file_name){std::ifstream fp(fi…