自定义view,用来测试屏幕
public class BezierGestureTrackView extends View {
private Bitmap mBufferBitmap;
private Canvas mBufferCanvas;
public BezierGestureTrackView(Context context) {
super(context);
}
PointF pointF;
Paint paint;
Paint paint2;
Path p,path ;
@ColorInt public static final int YELLOW = 0xFFFFFF00;
@ColorInt
public static final int CYAN = 0xFF00FFFF;
public static final int c1 = 0xEF8A97;
public static final int c2 = 0xFBD2A8;
public BezierGestureTrackView(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
paint.setStyle(Paint.Style.STROKE);//设置画笔的填充模式
paint.setStrokeJoin(Paint.Join.ROUND);//设置画笔图形接触时笔迹的形状
paint.setStrokeCap(Paint.Cap.ROUND);//设置画笔离开画板时笔迹的形状
paint.setStrokeWidth(8);//设置画笔粗细 6
paint.setAntiAlias(true);//设置抗锯齿
paint.setColor(Color.WHITE);
initPaint();
// BitmapFactory.decodeResource(getResources(), R.drawable.hbbg);
}
//新建两个SparseArray<Path>用来保存我们画出的Path对象,具体为什么之后会解释
//mActivePointers用来保存当前正在画的Path
SparseArray<Path> mActivePointers = new SparseArray<>();
//truePointers用来保存所有的Path,在onDraw()方法里面我们也是绘制这里的所有Path
SparseArray<Path> truePointers = new SparseArray<>();
//保存单个点
private int i=0;
private float[] a= new float[1000];
//重写onTouchEvent()方法
@Override
public boolean onTouchEvent(MotionEvent event) {
//获取当前DOWN或者UP的是手指的index
int curPointerIndex = event.getActionIndex();
//通过index获得当前手指的id
int curPointerId = event.getPointerId(curPointerIndex);
//获取当前正在发生的事件
int actionMasked = event.getActionMasked();
switch (actionMasked) {
//不管是第一个还是第N个手指落下,都执行以下方法:
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
//新建一个PointF对象用来保存点的坐标
pointF = new PointF();
pointF.x = event.getX(curPointerIndex);
pointF.y = event.getY(curPointerIndex);
//每当有手指下落时,都新建一个Path,并移动到手指落下的点
Path p = new Path();
p.moveTo(pointF.x, pointF.y);
//将新建的path添加到mActivePointers中
mActivePointers.append(curPointerId, p);
//保存单个点位置
if (i<998){
a[i++]=event.getX(curPointerIndex);
a[i++]=event.getY(curPointerIndex);
}
break;
case MotionEvent.ACTION_MOVE:
//当有手指移动时,遍历mActivePointers,注意这里遍历的条件并不是mActivePointers.size(),而是event.getPointerCount()
//也就是只监控当前所有正在滑动的手指数,另外在MotionEvent.ACTION_UP事件中,抬起的手指已经从mActivePointers中删除了
for (int size = event.getPointerCount(), i = 0; i < size; i++) {
//获取mActivePointers中的每一个Path
path = mActivePointers.get(event.getPointerId(i));
if (path != null) {
//更新每一个Path将得到的点连线
path.lineTo(event.getX(i), event.getY(i));
}
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
//当手指抬起时,代表已经绘制完毕,取得抬起的手指绘制图线实例,传入truePointers让Drow()绘制
path = mActivePointers.get(curPointerId);
truePointers.append(truePointers.size(), path);
//从mActivePointers中将抬起的手指删除
mActivePointers.remove(curPointerId);
break;
}
//重绘
invalidate();
return true;
}
private void initBuffer(){
mBufferBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
mBufferCanvas = new Canvas(mBufferBitmap);
}
@Override
protected void onDraw(Canvas canvas) {
//canvas.drawColor(Color.BLACK);
// Bitmap srcBitmap= BitmapFactory.decodeResource(getResources(), R.drawable.hbbg);
// canvas.drawBitmap(srcBitmap,0f,0f,null);
//遍历mActivePointers,因为只有当手指抬起时Path才被加入truePointers,此时truePointers里面还没有保存当前正在绘制的图线
//如果没有遍历mActivePointers,则图线不会即时显示,只有在抬起手指的瞬间,图线才会一起显示
for (int size = mActivePointers.size(), i = 0; i < size; i++) {
Path path = mActivePointers.valueAt(i);
canvas.drawPath(path, paint);
}
//遍历truePointers,这里保存的是当前正在画的图线
for (int size = truePointers.size(), i = 0; i < size; i++) {
path = truePointers.valueAt(i);
//绘制truePointers里的所有Path
canvas.drawPath(path, paint);
}
if (pointF!=null){
//canvas.drawPoint(pointF.x, pointF.y,paint2);
canvas.drawPoints(a, paint2);
for (int j = 0; j < a.length; j++) {
Log.e("TAG","a:"+a[i]+"a的长度:"+a.length);
}
}
}
// public void clean(){
//// Canvas canvas = sh.lockCanvas();
////
////
//// if(canvas!=null){
//// Paint paint = new Paint();
//// paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
//// canvas.drawPaint(paint);
//////canvas.drawColor(Color.BLUE);
//// }
// Log.e("BezierGestureTrackView","CLEAN");
// }
public void clear() {
if (mBufferBitmap != null) {
if (mActivePointers!=null){
mActivePointers.clear();
}
if (truePointers != null) {
truePointers.clear();
}
mBufferBitmap.eraseColor(Color.TRANSPARENT);
invalidate();
}
}
private void initPaint() {
paint2 = new Paint();
//LinearGradient lg=new LinearGradient(0,0,100,100,Color.RED,Color.BLUE, Shader.TileMode.MIRROR); //参数一为渐变起初点坐标x位
LinearGradient lg=new LinearGradient(0,0,100,100,CYAN,YELLOW, Shader.TileMode.MIRROR); //参数一为渐变起初点坐标x位
paint2.setStyle(Paint.Style.STROKE);//设置画笔的填充模式
paint2.setStrokeJoin(Paint.Join.ROUND);//设置画笔图形接触时笔迹的形状
paint2.setStrokeCap(Paint.Cap.ROUND);//设置画笔离开画板时笔迹的形状
paint2.setStrokeWidth(45);//设置画笔粗细 50
paint2.setAntiAlias(true);//设置抗锯齿
paint2.setColor(Color.WHITE);//设置抗锯齿
paint2.setShader(lg);
}
}
自定义view,用来测试屏幕的更多相关文章
- 自定义View和ViewGroup
为了扫除学习中的盲点,尽可能多的覆盖Android知识的边边角角,决定对自定义View做一个稍微全面一点的使用方法总结,在内容上面并没有什么独特的地方,其他大神们的博客上面基本上都有讲这方面的内容,如 ...
- Android 自定义View修炼-Android实现圆形、圆角和椭圆自定义图片View(使用BitmapShader图形渲染方法)
一.概述 Android实现圆角矩形,圆形或者椭圆等图形,一般主要是个自定义View加上使用Xfermode实现的.实现圆角图片的方法其实不少,常见的就是利用Xfermode,Shader.本文直接继 ...
- 自定义View实现五子棋游戏
成功的路上一点也不拥挤,因为坚持的人太少了. ---简书上看到的一句话 未来请假三天顺带加上十一回家结婚,不得不说真是太坑了,去年婚假还有10天,今年一下子缩水到了3天,只能赶着十一办事了. 最近还在 ...
- Android自定义View(一、初体验自定义TextView)
转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51454685 本文出自:[openXu的博客] 目录: 继承View重写onDraw方法 自 ...
- Android的自定义View及View的绘制流程
目标:实现Android中的自定义View,为理清楚Android中的View绘制流程“铺路”. 想法很简单:从一个简单例子着手开始编写自定义View,对ViewGroup.View类中与绘制View ...
- 自定义View和ViewGroup(有这一篇就够了)
为了扫除学习中的盲点,尽可能多的覆盖Android知识的边边角角,决定对自定义View做一个稍微全面一点的使用方法总结,在内容上面并没有什么独特的地方,其他大神们的博客上面基本上都有讲这方面的内容,如 ...
- 【朝花夕拾】Android自定义View篇之(五)Android事件分发机制(上)Touch三个重要方法的处理逻辑
前言 转载请注明,转自[https://www.cnblogs.com/andy-songwei/p/10998855.html]谢谢! 在自定义View中,经常需要处理Android事件分发的问题, ...
- 【朝花夕拾】Android自定义View篇之(四)自定义View的三种实现方式及自定义属性使用介绍
前言 转载请声明,转自[https://www.cnblogs.com/andy-songwei/p/10979161.html],谢谢! 尽管Android系统提供了不少控件,但是有很多酷炫效果仍然 ...
- Android进阶之绘制-自定义View完全掌握(二)
这是自定义View系列的第二篇博客,我们继续来学习关于自定义View的知识. 今天我们来实现一下广告条案例. 我们要实现的是这样的一个效果. 要想实现这样的效果,我们可以借助ViewPager控件,然 ...
- 【转载】自定义View,有这一篇就够了
为了扫除学习中的忙点,尽可能多的覆盖Android知识的边边角角,决定对自定义View做一个稍微全面一点的使用方法总结,在内容上面并没有什么独特的地方,其他大神们博客上面基本上都有讲这方面的内容,如果 ...
随机推荐
- Windows关闭网络防火墙教程
Win10操作系统 1. 打开控制面板,点击"系统和安全" 2. 点击"Windows Defender 防火墙" 3. 点击"启用或关闭Window ...
- [OpenCV实战]51 基于OpenCV实现图像极坐标变换与逆变换
在图像处理领域中,经常通过极坐标与笛卡尔直角坐标的互转来实现图像中圆形转为方形,或者通过极坐标反变换实现方形转圆形.例如钟表的表盘,人眼虹膜,医学血管断层都需要用到极坐标变换来实现圆转方. 文章目录 ...
- [OpenCV实战]36 使用OpenCV在视频中实现简单背景估计
目录 1 时间中值滤波 2 使用中值进行背景估计 3 帧差分 4 总结和代码 5 参考 许多计算机视觉应用中,硬件配置往往较低.在这种情况下,我们必须使用简单而有效的技术.在这篇文章中,我们将介绍一种 ...
- [OpenCV实战]29 使用OpenCV实现红眼自动去除
目录 1 红眼消除 1.1 眼部检测 1.2 红眼遮掩 1.3 清除瞳孔掩模空洞 1.4 红眼修复 2 结果与完整代码 2.1 结果 2.2 代码 3 参考 在本教程中,我们将学习如何完全自动地从照片 ...
- 前菜--Numpy
import numpy as np NumPy : numberial python NumPy的核心:数据结构 ndarray 1.1 数组方法 np.array 创建数组 基本语法:np.arr ...
- python之路56 dajngo最后一天 csrf跨站请求 auth模块登录注册方法
csrf跨站请求伪造 钓鱼网站:模仿一个正规的网站 让用户在该网站上做操作 但是操作的结果会影响到用户正常的网站账户 但是其中有一些猫腻 eg:英语四六级考试需要网上先缴费 但是你会发现卡里的钱扣了但 ...
- 【大型软件开发】浅谈大型Qt软件开发(一)开发前的准备——在着手开发之前,我们要做些什么?
前言 最近我们项目部的核心产品正在进行重构,然后又是年底了,除了开发工作之外项目并不紧急,加上加班时间混不够了....所以就忙里偷闲把整个项目的开发思路聊一下,以供参考. 鉴于接下来的一年我要操刀这个 ...
- Hugging Face 2023 实习生招募计划
Hugging Face 2023 实习生招募计划 想参与到 <王婆卖瓜>「最酷的 AI 社区」</王婆卖瓜>,共同构建未来吗?今天,我们为大家分享 Hugging Face ...
- MySQL 更新数据 不同条件(批量)更新不同值
一般在更新时会遇到以下场景:1.全部更新:2.根据条件更新字段中的某部分内容:3.根据不同的条件更新不同的值,以下是几种场景中常用的update方法. 一.方法分类 二.具体用法 (1)根据条件更新值 ...
- Vue导出模板、使用前端js办法导出表格数据、导入表格前端读取表格数据、导入表格发送后端读取数据
以下是几种用的较多的函数方法,可以参考使用. // 導出1 myExport() { // post請求文件寫法1 const url = 'http://XXXX/XXXX/XXXX/XXXX' c ...