至于角度,布吉岛了
卡券核销功能(对应老版的微助手)是核销微信平台的卡券二维码如微客巴巴商城订单二维码、大转盘、刮刮卡中奖二维码、优惠券、团购券等。店长可以核销该门店的所有卡券,店员需要找店长开通启用卡券核销功能方可使用。SurfaceView是View的继承结构中一个比较特殊的子类,它的作用是提供一个第二线程来完成图形的绘制。因此应用程序不需要等待View的图形绘制,第二线程会异步完成图形的绘制。SurfaceView实现的步骤:
继续SurfaceView并实现SurfaceHolder.Callback接口,该接口提供了SurfaceView创建、属性发生变化、销毁的时间点,那么你可以在适当的时间点完成具体的工作。
在SurfaceView初始化的时候调用SurfaceView.getHolder()方法获取一个SurfaceHolder,SurfaceHolder用于管理SurfaceView的工作过程。为了让SurfaceHolder起作用,必须为SurfaceHolder添加回调方法(即第一步实现的SurfaceHolder.Callback):
[java] view plaincopyprint?
SurfaceHolder.addCallBack(SurfaceHolder.Callback)
在SurfaceView内创建第二线程的内部类(暂命名为SecondThread),它的主要任务是完成Canvas的图形绘制。为了能让SecondThread获得Canvas实例,必须给SecondThread传递在步骤二中获得的SurfaceHolder。现在就可以通过SurfaceHolder.lockCanvas()方法得到Canvas实例,并在Canvas上绘制图形。当图形绘制完成后,必须马上调用SurfaceHolder.unlockCanvasAndPost()为Canvas解锁,使其他线程可以使用该画布。
有几个注意点:
每一次通过SurfaceHolder获取的Canvas都会保持上一次绘制的状态。如果需要重新绘制图形,可以通过调用Canvas.drawColor()或Canvas.drawBitmap()来擦除上次遗留的图形。
并不一定只用第二线程来绘制图形,也可以开启第三,第四个线程来绘制图形。
注意线程安全。
不需要像View一样,调用invalidate()方法来指示图形的刷新。
SurfaceView的一个范例:
[java] view plaincopyprint?
package com.sin90lzc.android.sample
import java.util.ArrayList
import java.util.Collections
import java.util.List
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.util.Log
import android.view.KeyEvent
import android.view.SurfaceHolder
import android.view.SurfaceView
public class CanvasView extends SurfaceView implements SurfaceHolder.Callback {
public static class Point {
private float x
private float y
public Point(float x, float y) {
this.x = x
this.y = y
}
public float getX() {
return x
}
public void setX(float x) {
this.x = x
}
public float getY() {
return y
}
public void setY(float y) {
this.y = y
}
public Point nextPoint(Orien o) {
float tempX = x
float tempY = y
switch (o) {
case UP:
tempY = y - LINE_LENGTH
break
case DOWN:
tempY = y + LINE_LENGTH
break
case LEFT:
tempX = x - LINE_LENGTH
break
case RIGHT:
tempX = x + LINE_LENGTH
break
case UNKNOWN:
break
}
return new Point(tempX, tempY)
}
}
enum Orien {
UP, LEFT, DOWN, RIGHT, UNKNOWN
}
public static class DrawThread extends Thread {
private List<Point>points = Collections
.synchronizedList(new ArrayList<Point>())
private boolean mRun
private Paint mPaint
private Orien curOrien
public synchronized void setRun(boolean run) {
this.mRun = run
notifyAll()
}
public synchronized boolean getRun() {
while (!mRun) {
try {
wait()
} catch (InterruptedException e) {
e.printStackTrace()
}
}
return mRun
}
//当按上下左右键时,生成相应的点坐标
private synchronized boolean doKeyDown(int KeyCode, KeyEvent event) {
synchronized (holder) {
Point p = null
switch (KeyCode) {
case KeyEvent.KEYCODE_DPAD_UP:
if (curOrien != Orien.DOWN) {
curOrien = Orien.UP
p = curPoint.nextPoint(curOrien)
}
break
case KeyEvent.KEYCODE_DPAD_DOWN:
if (curOrien != Orien.UP) {
curOrien = Orien.DOWN
p = curPoint.nextPoint(curOrien)
}
break
case KeyEvent.KEYCODE_DPAD_LEFT:
if (curOrien != Orien.RIGHT) {
curOrien = Orien.LEFT
p = curPoint.nextPoint(curOrien)
}
break
case KeyEvent.KEYCODE_DPAD_RIGHT:
if (curOrien != Orien.LEFT) {
curOrien = Orien.RIGHT
p = curPoint.nextPoint(curOrien)
}
break
default:
curOrien = Orien.UNKNOWN
}
if (p != null) {
curPoint = p
points.add(p)
setRun(true)
}
Log.i(LOG_TAG, curOrien.toString())
}
return true
}
//当释放按键时,停止绘图
private synchronized boolean doKeyUp(int KeyCode, KeyEvent event) {
synchronized (holder) {
setRun(false)
curOrien = Orien.UNKNOWN
}
return true
}
SurfaceHolder holder
private Point curPoint
public DrawThread(SurfaceHolder holder) {
this.holder = holder
mPaint = new Paint()
mPaint.setColor(Color.GREEN)
curPoint = new Point(50, 50)
points.add(curPoint)
}
public void resetPoint() {
}
private void doDraw(Canvas canvas) {
for (int i = 0i + 1 <points.size()i += 1) {
Point lp = points.get(i)
Point np = points.get(i + 1)
canvas.drawLine(lp.getX(), lp.getY(), np.getX(), np.getY(),
mPaint)
}
}
@Override
public void run() {
Canvas canvas = null
while (getRun()) {
try {
canvas = holder.lockCanvas()
synchronized (holder) {
doDraw(canvas)
}
} finally {
holder.unlockCanvasAndPost(canvas)
setRun(false)
}
}
}
}
private DrawThread thread
public static final String LOG_TAG = "CanvasView"
private static final int LINE_LENGTH = 30
public CanvasView(Context context) {
super(context)
}
public CanvasView(Context context, AttributeSet attrs) {
super(context, attrs)
//SurfaceView由SurfaceHolder管理
SurfaceHolder holder = getHolder()
holder.addCallback(this)
thread = new DrawThread(holder)
thread.start()
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return thread.doKeyDown(keyCode, event)
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
return thread.doKeyUp(keyCode, event)
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Log.i(LOG_TAG, "surfaceChanged")
thread.resetPoint()
thread.setRun(true)
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
Log.i(LOG_TAG, "surfaceCreated")
thread.resetPoint()
thread.setRun(true)
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.i(LOG_TAG, "surfaceDestroyed")
thread.setRun(false)
}
}
Notice:例子中,没一次按下方向键都得把所有坐标重新绘制一遍。如果只是绘制最后一次没绘制的点时,不知道为什么会变成虚线,有待解决。