Android 에서 Surface View 와 view 가 터치 궤적 을 그립 니 다.

머리말
         빈 패 널 을 실현 하려 면 위 에 손 이 미 끄 러 지 는 궤적 을 그 릴 수 있다 는 작은 수요 가 있다.일반적으로 두 가지 실현 방식,view 또는 surfaceview.두 가지 가 어떻게 이 루어 졌 는 지 살 펴 보 자.
2.실현 원리
         먼저 실현 원 리 를 간단히 말 하 다.
       (1)화이트 비트 맵 을 화판 으로 사용
       (2)canvas 로 bitmap 에 선 그리 기
       (3)매 끄 러 운 곡선 을 그리 기 위해 서 는 canvas 의 drawPath(Path,Paint)방법 을 사용 해 야 한다.
       (4)베 어 셀 곡선 을 동시에 사용 하여 곡선 을 더욱 매 끄 럽 게 한다.
3.View 실현
코드 를 직접 붙 였 습 니 다:

package picturegame.view; 
 
import android.annotation.SuppressLint; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Paint.Style; 
import android.graphics.Path; 
import android.util.AttributeSet; 
import android.view.MotionEvent; 
import android.view.View; 
 
import com.winton.picturegame.R; 
 
/** 
* @ClassName: GameView 
* @Description: TODO(              ) 
* @author Winton [email protected] 
* @date 2015 9 26    8:54:37 
* 
*/ 
public class GameView extends View{ 
  
 private Paint paint = null; // 
  
 private Bitmap originalBitmap = null;//    
  
 private Bitmap new1Bitmap = null; 
  
 private Bitmap new2Bitmap = null; 
  
 private float clickX =0; 
  
 private float clickY=0; 
  
 private float startX=0; 
  
 private float startY=0; 
  
 private boolean isMove = true; 
  
 private boolean isClear = false; 
  
 private int color =Color.RED;//       
  
 private float strokeWidth =20f;//       
  
 Path mPath; 
  
  
 
 public GameView(Context context) { 
  this(context,null); 
  // TODO Auto-generated constructor stub 
 } 
 public GameView(Context context,AttributeSet atts) { 
  this(context,atts,0); 
  // TODO Auto-generated constructor stub 
 } 
 @SuppressWarnings("static-access") 
 public GameView(Context context,AttributeSet atts,int defStyle) { 
  super(context,atts,defStyle); 
  // TODO Auto-generated constructor stub 
   
  originalBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.default_pic).copy(Bitmap.Config.ARGB_8888, true);//      
  new1Bitmap=originalBitmap.createBitmap(originalBitmap); 
  mPath=new Path(); 
 } 
 
 //   
 @SuppressWarnings("static-access") 
 public void clear(){ 
  isClear =true; 
  new2Bitmap=originalBitmap.createBitmap(originalBitmap); 
  invalidate();//   
 } 
  
 public void setStrokeWidth(float width){ 
  this.strokeWidth=width; 
  initPaint(); 
 } 
 @Override 
 protected void onDraw(Canvas canvas) { 
  // TODO Auto-generated method stub 
  super.onDraw(canvas); 
  canvas.drawBitmap(writer(new1Bitmap),0,0, null); 
   
 } 
  
 @SuppressLint("ClickableViewAccessibility") 
 @Override 
 public boolean onTouchEvent(MotionEvent event) { 
  // TODO Auto-generated method stub 
   
   
  clickX =event.getX(); 
   
  clickY=event.getY(); 
   
  if(event.getAction()==MotionEvent.ACTION_DOWN){ 
   //          
    
   startX=clickX; 
   startY=clickY; 
   mPath.reset(); 
   mPath.moveTo(clickX, clickY); 
    
//   isMove =false; 
//   invalidate(); 
//   return true; 
  } 
  else if(event.getAction()==MotionEvent.ACTION_MOVE){ 
   //        
   float dx=Math.abs(clickX-startX); 
   float dy=Math.abs(clickY-startY); 
//   if(dx>=3||dy>=3){ 
    //                     
    float cX = (clickX + startX) / 2; 
    float cY = (clickY + startY) / 2; 
    mPath.quadTo(startX,startY, cX, cY); 
     
    startX=clickX; 
    startY=clickY; 
     
//   } 
//   isMove =true; 
//   invalidate(); 
//   return true; 
  } 
   
   
  invalidate(); 
  return true; 
 } 
  
 
 /** 
 * @Title: writer 
 * @Description: TODO(               ) 
 * @param @param pic 
 * @param @return      
 * @return Bitmap      
 * @throws 
 */ 
 public Bitmap writer(Bitmap pic){ 
  initPaint(); 
   
  Canvas canvas =null; 
  if(isClear){ 
   canvas=new Canvas(new2Bitmap); 
  }else{ 
   canvas=new Canvas(pic); 
  } 
   
   //canvas.drawLine(startX, startY, clickX, clickY, paint);//   
   canvas.drawPath(mPath, paint); 
  if(isClear){ 
   return new2Bitmap; 
  } 
  return pic; 
 } 
  
 private void initPaint(){ 
   
  paint = new Paint();//      
   
  paint.setStyle(Style.STROKE);//      
   
  paint.setAntiAlias(true);//        
   
  paint.setColor(color);//       
   
  paint.setStrokeWidth(strokeWidth);//       
 } 
  
  
 /** 
 * @Title: setColor 
 * @Description: TODO(      ) 
 * @param @param color      
 * @return void      
 * @throws 
 */ 
 public void setColor(int color){ 
   
  this.color=color; 
  initPaint(); 
 } 
  
 public Bitmap getPaint(){ 
  return new1Bitmap; 
 } 
} 
효과 보기:

기본적으로 수 요 를 만족시키다.
3.surfaceView 실현

package picturegame.view; 
 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Paint; 
import android.graphics.Paint.Style; 
import android.graphics.Path; 
import android.util.AttributeSet; 
import android.view.MotionEvent; 
import android.view.SurfaceHolder; 
import android.view.SurfaceHolder.Callback; 
import android.view.SurfaceView; 
 
import com.winton.picturegame.R; 
 
public class GameViewSurface extends SurfaceView implements Callback,Runnable{ 
  
  
 /**          **/ 
 boolean mRunning = false; 
  
 /**      **/ 
 boolean mIsRunning = false; 
  
 /** 50       **/  
 public static final int TIME_IN_FRAME = 50; 
 
 private int paintColor=android.graphics.Color.WHITE;//          
  
 private float paintWidth=2f;//       
  
 private Style paintStyle=Style.STROKE;//       
  
 private int paintAlph=255;//      
  
 private Path mPath;//   
  
 private Paint mPaint;//   
  
 private float startX=0.0f;//  x 
  
 private float startY=0.0f;//  Y 
  
 private SurfaceHolder surfaceHolder; 
  
 public Canvas mCanvas; 
  
 public boolean first=true; 
  
 Bitmap bg; 
  
 public GameViewSurface(Context context){ 
  this(context,null); 
 } 
 public GameViewSurface(Context context,AttributeSet attrs){ 
  this(context,attrs,0); 
 } 
 public GameViewSurface(Context context, AttributeSet attrs, int defStyle) { 
  super(context, attrs, defStyle); 
  // TODO Auto-generated constructor stub 
  this.setFocusable(true);//    view       
   
  surfaceHolder=getHolder(); 
  surfaceHolder.addCallback(this); 
   
  mPath=new Path(); 
  initPaint(); 
   
  bg = BitmapFactory.decodeResource(getResources(), R.drawable.default_pic).copy(Bitmap.Config.ARGB_8888, true);//      
 } 
 /** 
 * @Title: initPaint 
 * @Description: TODO(     ) 
 * @param       
 * @return void      
 * @throws 
 */ 
 private void initPaint(){ 
  mPaint=new Paint(); 
  mPaint.setAntiAlias(true);//     
  mPaint.setColor(paintColor);//     
  mPaint.setAlpha(paintAlph);//      
  mPaint.setStyle(paintStyle);//       
  mPaint.setStrokeWidth(paintWidth);//       
 } 
  
 public void doDraw(){ 
  mCanvas=surfaceHolder.lockCanvas(); 
  mCanvas.drawPath(mPath, mPaint);//   
  surfaceHolder.unlockCanvasAndPost(mCanvas); 
 }  
 @Override 
 public boolean onTouchEvent(MotionEvent event) { 
  // TODO Auto-generated method stub 
   
  switch (event.getAction()) { 
  case MotionEvent.ACTION_DOWN: 
   //         
   doTouchDown(event); 
   break; 
  case MotionEvent.ACTION_MOVE: 
   //       
   doTouchMove(event); 
   break; 
    
  case MotionEvent.ACTION_UP: 
   //       
    
   break; 
    
 
  default: 
   break; 
  } 
  return true; 
 } 
  
 /** 
 * @Title: doTouchDown 
 * @Description: TODO(             ) 
 * @param @param event      
 * @return void      
 * @throws 
 */ 
 private void doTouchDown(MotionEvent event){ 
   
  float touchX=event.getX(); 
  float touchY=event.getY(); 
  startX=touchX; 
  startY=touchY; 
  mPath.reset(); 
  mPath.moveTo(touchX, touchY); 
 } 
  
 /** 
 * @Title: doTouchMove 
 * @Description: TODO(             ) 
 * @param @param event      
 * @return void      
 * @throws 
 */ 
 private void doTouchMove(MotionEvent event){ 
   
  float touchX=event.getX(); 
  float touchY=event.getY(); 
   
  float dx=Math.abs(touchX-startX);//      
   
  float dy =Math.abs(touchY-startX);//      
   
  if(dx>3||dy>3){ 
   float cX=(touchX+startX)/2; 
   float cY=(touchY+startY)/2; 
   mPath.quadTo(startX, startY, cX, cY); 
    
   startX=touchX; 
   startY=touchY; 
    
  } 
   
 } 
  
 public void setPaintColor(int paintColor) { 
  this.paintColor = paintColor; 
  initPaint(); 
 } 
 public void setPaintWidth(float paintWidth) { 
  this.paintWidth = paintWidth; 
  initPaint(); 
 } 
 public void setPaintStyle(Style paintStyle) { 
  this.paintStyle = paintStyle; 
  initPaint(); 
 } 
 public void setPaintAlph(int paintAlph) { 
  this.paintAlph = paintAlph; 
  initPaint(); 
 } 
  
  
 @Override 
 public void run() { 
  // TODO Auto-generated method stub 
  while (mIsRunning) { 
    
   /**             **/ 
   long startTime = System.currentTimeMillis(); 
   /**            **/ 
   synchronized(surfaceHolder){ 
    doDraw(); 
   } 
    
   /**             **/ 
   long endTime = System.currentTimeMillis(); 
  
   /**               **/ 
   int diffTime = (int) (endTime - startTime); 
  
   /**          50  **/ 
   while (diffTime <= TIME_IN_FRAME) { 
    diffTime = (int) (System.currentTimeMillis() - startTime); 
    /**      **/ 
    Thread.yield(); 
   } 
  
   } 
   
 } 
 @Override 
 public void surfaceCreated(SurfaceHolder holder) { 
  // TODO Auto-generated method stub 
  mCanvas =surfaceHolder.lockCanvas(); 
  mCanvas.drawBitmap(bg, 0,0, null); 
  surfaceHolder.unlockCanvasAndPost(mCanvas); 
   
  mIsRunning=true; 
  new Thread(this).start(); 
 } 
 @Override 
 public void surfaceChanged(SurfaceHolder holder, int format, int width, 
   int height) { 
  // TODO Auto-generated method stub 
   
 } 
 @Override 
 public void surfaceDestroyed(SurfaceHolder holder) { 
  // TODO Auto-generated method stub 
   mIsRunning = false; 
 } 
  
  
} 
실행 효과 보기:

내 가 배경 을 설정 하지 않 을 때 는 문제 가 없 지만 배경 을 사용 하면 끊임없이 반 짝 거 린 다.친구 들 이 알 고 있 는 지 모 르 겠 으 니 말 해도 된다.
여러분 은 본문 을 읽 을 수 있 습 니 다'Android Surface View 터치 궤적 반 짝 임 문 제 를 해결 하 는 방법',여러분 의 학습 에 도움 이 될 수 있 습 니 다.
총화
두 가지 방식 이 모두 실 현 될 수 있 고 자세히 비교 해 보면 surfaceview 의 응답 속도 가 view 보다 훨씬 빠 르 고 view 는 surfaceview 와 더욱 쉽게 실 현 될 것 이다.
view 는 수 동적 으로 업 데 이 트 된 애니메이션 을 표시 하 는 데 사용 되 며,surfaceview 는 화면 에 달 리 는 강 아 지 를 표시 하 는 등 주동 적 으로 업 데 이 트 된 애니메이션 을 표시 합 니 다.
view 업데이트 인 터 페 이 스 는 UI 메 인 스 레 드 입 니 다.surfaceview 는 스스로 스 레 드 업데이트 인터페이스 를 만 듭 니 다.
이상 이 바로 본문의 전체 내용 이 니 여러분 이 좋아 하 시 기 를 바 랍 니 다.

좋은 웹페이지 즐겨찾기