自定义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做一个稍微全面一点的使用方法总结,在内容上面并没有什么独特的地方,其他大神们博客上面基本上都有讲这方面的内容,如果 ... 
随机推荐
- MySQL函数--时间格式--流程控制if判断
			目录 一:函数 1.MySQL什么是函数? 2.通过help查看函数帮助 3.移除指定字符 4.大小写转换 5.获取左右起始指定个数字符 6.返回读音相似值(对英文效果) 二:时间格式实战案例 1.时 ... 
- 【FAQ】在华为鸿蒙车机上集成华为帐号的常见问题总结
			随着新一代信息技术与汽车产业的深度融合,智能网联汽车正逐渐成为汽车产业发展的战略制高点,无论是传统车企还是新势力都瞄准了"智能座舱"这种新一代人机交互方式.面对竞争如此激烈的车机市 ... 
- jmeter json提取器提取某个属性的所有值
			json 提取器各字段说明: Variable names:保存的变量名,后面使用${Variable names}引用 JSON Path expressions:调试通过的json path表达 ... 
- AcWing341. 洛谷P1073, NOIP2009 最优贸易
			AcWing题目传送门 洛谷题目传送门 题目大意 \(~~~~~~\)一个投机倒把的奸商想要通过城市不太健全的贸易系统坑点钱,任意城市都可以买入或者卖出水晶球,他想尽量在便宜的城市买入,在贵的城市卖出 ... 
- 【转载】WebBrowser控件的常用方法、属性和事件
			1. 属性 属性 说明 Application 如果该对象有效,则返回掌管WebBrowser控件的应用程序实现的自动化对象(IDispatch).如果在宿主对象中自动化对象无效,这个程序将返回Web ... 
- [OpenCV实战]32 使用OpenCV进行非真实感渲染
			目录 1 保边滤波的频域变换 1.1 保边滤波器Edge Preserving Filter 1.1.1 函数调用 1.1.2 edgePreservingFilter结果 1.2 细节增强 1.3 ... 
- [OpenCV实战]21 使用OpenCV的Eigenface
			目录 1 PCA 1.1 方差是什么 1.2 什么是PCA 1.3 什么是矩阵的特征向量和特征值? 1.4 如何计算PCA 2 什么是EigenFaces? 2.1 将图像作为向量 2.2 如何计算如 ... 
- 深入Typescript--03-Typescript中的类(努力加餐饭)
			Typescript中的类 一.TS中定义类 class Pointer{ x!:number; // 实例上的属性必须先声明 y!:number; constructor(x:number,y?:n ... 
- 0基础搭建基于OpenAI的ChatGPT钉钉聊天机器人
			前言:以下文章来源于我去年写的个人公众号.最近chatgpt又开始流行,顺便把原文内容发到博客园上遛一遛. 注意事项和指引: 注册openai账号,需要有梯子进行访问,最好是欧美国家的IP,亚洲国家容 ... 
- 【Spring】Bean注册注解
			@Configuration 同@Component,将标注的类作为一个组件,区别是会使用Cglib动态代理,因此使用该注解的类不能是final的 与@Component的区别可见:Configura ... 
