服务器之家

服务器之家 > 正文

解决Android SurfaceView绘制触摸轨迹闪烁问题的方法

时间:2021-06-21 17:50     来源/作者:Android开发网

本文分享了解决surfaceview触摸轨迹闪烁问题的方法,供大家参考,具体内容如下

第一种解决surfaceview触摸轨迹闪烁问题的方法:

由于surfaceview使用双缓存机制,两张画布轮流显示到屏幕上。那么,要存储触摸轨迹并避免两张画布内容不一致造成的闪烁问题,完全可以利用保存绘制过程并不断重新绘制的方法解决闪烁,而且这样还顺带解决了多次试验中偶尔出现的因为moveto()函数不能读取到参数执行默认设置(参数设为上次的触摸点)而出现的断线连接闪烁问题,详细代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package com.tobacco.touchdraw;
import java.util.arraylist;
import android.content.context;
import android.graphics.canvas;
import android.graphics.color;
import android.graphics.paint;
import android.graphics.path;
import android.view.motionevent;
import android.view.surfaceholder;
import android.view.surfaceview;
import android.view.view;
import android.view.surfaceholder.callback;
import android.view.view.ontouchlistener;
public class lsurfaceview extends surfaceview implements callback,ontouchlistener,runnable{
 private surfaceholder sfh;
 private canvas canvas;
 private paint paint;
 private path path;
 private arraylist<path> paths;
 private boolean flag;
 public lsurfaceview(context context) {
 super(context);
 sfh=this.getholder();
 sfh.addcallback(this);
 paint=new paint();
 paint.setcolor(color.red);
 paint.setantialias(true);
 paint.setstrokewidth(4);
 paint.setstyle(paint.style.stroke);
 paint.setstrokecap(paint.cap.round);
 paths=new arraylist<path>();
 path=new path();
 }
 public void mydraw(motionevent e){
 int action=e.getaction();
 switch(action){
 case motionevent.action_down:
  path.moveto(e.getx(),e.gety());
  break;
 case motionevent.action_move:
  path.lineto(e.getx(),e.gety());
  break;
 case motionevent.action_up:
  //path.close();
  path path1=new path(path);
  paths.add(path1);
  path.reset();
  break;
 }
 
 
 }
 @override
 public void surfacechanged(surfaceholder arg0, int arg1, int arg2, int arg3) {
 
 
 }
 @override
 public void surfacecreated(surfaceholder holder) {
 flag=true;
 setontouchlistener(this);
 new thread(this).start();
 
 }
 @override
 public void surfacedestroyed(surfaceholder holder) {
 flag=false;
 }
 @override
 public boolean ontouch(view v, motionevent event) {
 mydraw(event);
 return true;
 }
 @override
 public void run() {
 while(flag){
  long start=system.currenttimemillis();
  canvas=sfh.lockcanvas();
  if(canvas!=null){
  canvas.drawcolor(color.black);
  for(int i=0;i<paths.size();i++)
   canvas.drawpath(paths.get(i),paint);
  canvas.drawpath(path,paint);
  sfh.unlockcanvasandpost(canvas);
  }
  long end=system.currenttimemillis();
  try{
  if(end-start<30){
   thread.sleep(30-(end-start));
  }
  }
  catch(exception e){
  }
 }
 
 }
}

这里还要注意的是:arraylist保存的是对象的引用,所以要在每次添加时都新建一个对象实体。

第二种解决surfaceview触摸轨迹闪烁问题的方法:

处理触屏轨迹的绘制时,用到了surfaceview,建立path对象,在点击时开始设置path对象,滑动过程中记录触摸点,离开后重新设置path对象,因不能阻塞主线程,所以新建了一个子线程来不断刷新屏幕,也就是将path不断绘制。但是,接着就出现了一个问题:屏幕中每条轨迹线的终点都会有一小段直线段不断闪烁。猜测可能是lockcanvas()获取的对象区域不一样,就试着使用了lockcanvas(rect re),但是,运行后发现还是没有解决问题;接着想到可能是因为每次lockcanvas()后获取的对象不同,就在主线程中添加了一个canvas对象,每次都在canvas对象中修改画面,然后提交显示,但是,程序运行后效果丝毫没有改变!程序代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package com.tobacco.touchdraw;
import android.content.context;
import android.graphics.canvas;
import android.graphics.color;
import android.graphics.paint;
import android.graphics.path;
import android.view.motionevent;
import android.view.surfaceholder;
import android.view.surfaceview;
import android.view.view;
import android.view.surfaceholder.callback;
import android.view.view.ontouchlistener;
public class mysurfaceview extends surfaceview implements callback,ontouchlistener,runnable{
 private surfaceholder sfh;
 private canvas canvas;
 private paint paint;
 private float lastx,lasty;
 private path path;
 private boolean flag;
 public mysurfaceview(context context) {
 super(context);
 sfh=this.getholder();
 sfh.addcallback(this);
 paint=new paint();
 paint.setcolor(color.red);
 paint.setantialias(true);
 paint.setstrokewidth(5);
 paint.setstyle(paint.style.stroke);
 paint.setstrokecap(paint.cap.round);
 path=new path();
 
 }
 public void mydraw(motionevent e){
 int action=e.getaction();
 switch(action){
 case motionevent.action_down:
  path.moveto(e.getx(),e.gety());
  lastx=e.getx();
  lasty=e.gety();
  break;
 case motionevent.action_move:
  path.quadto(lastx,lasty,e.getx(),e.gety());
  lastx=e.getx();
  lasty=e.gety();
  break;
 case motionevent.action_up:
  //path.quadto(lastx,lasty,e.getx(),e.gety());
  path.reset();
  break;
 }
 
 
 }
 @override
 public void surfacechanged(surfaceholder arg0, int arg1, int arg2, int arg3) {
 
 
 }
 @override
 public void surfacecreated(surfaceholder holder) {
 flag=true;
 setontouchlistener(this);
 new thread(this).start();
 
 }
 @override
 public void surfacedestroyed(surfaceholder holder) {
 flag=false;
 }
 @override
 public boolean ontouch(view v, motionevent event) {
 mydraw(event);
 return true;
 }
 @override
 public void run() {
 while(flag){
  long start=system.currenttimemillis();
  canvas=sfh.lockcanvas();
  if(canvas!=null){
  canvas.drawpath(path,paint);
  sfh.unlockcanvasandpost(canvas);
  }
  long end=system.currenttimemillis();
  try{
  if(end-start<100){
   thread.sleep(100-(end-start));
  }
  }
  catch(exception e){
  }
 }
 
 }
}

以上就是本文的全部内容,希望能够帮助大家轻松解决surfaceview触摸轨迹闪烁问题。

相关文章

热门资讯

2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
2021德云社封箱演出完整版 2021年德云社封箱演出在线看
2021德云社封箱演出完整版 2021年德云社封箱演出在线看 2021-03-15
返回顶部

1099
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40