Android中怎么實(shí)現(xiàn)一個(gè)繪圖板,針對這個(gè)問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡單易行的方法。
目前創(chuàng)新互聯(lián)建站已為成百上千的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)頁空間、網(wǎng)站托管維護(hù)、企業(yè)網(wǎng)站設(shè)計(jì)、奉賢網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。
創(chuàng)建一個(gè)名為DrawView的類,該類繼承自android.view.View類。在該類中,首先定義程序中所需的屬性,然后添加構(gòu)造方法,并重寫onDraw(Canvas canvas)方法:
DrawView.java:
package com.example.test; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Path; import android.util.AttributeSet; import android.view.View; public class DrawView extends View{ private int view_width=0;//屏幕的寬度 private int view_height=0;//屏幕的高度 private float preX;//起始點(diǎn)的x坐標(biāo) private float preY;//起始點(diǎn)的y坐標(biāo) private Path path;//路徑 public Paint paint;//畫筆 Bitmap cacheBitmap=null;//定義一個(gè)內(nèi)存中的圖片,該圖片將作為緩沖區(qū) Canvas cacheCanvas=null;//定義cacheBitmap上的Canvas對象 /* * 功能:構(gòu)造方法 * */ public DrawView(Context context, AttributeSet attrs) { super(context, attrs); } /* * 功能:重寫onDraw方法 * */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); } }
創(chuàng)建布局文件,選擇幀布局,并加入上面創(chuàng)建的繼承了View的自定義畫圖控件:
res/layout/main.xml
在DrawView類的構(gòu)造方法中,首先獲取屏幕的高度和寬度,并創(chuàng)建一個(gè)與該View相同大小的緩存區(qū),然后創(chuàng)建一個(gè)新的畫面,并實(shí)例化一個(gè)路徑,再將內(nèi)存中的位圖繪制到cacheCanvas中,最后實(shí)例化一個(gè)畫筆,并設(shè)置畫筆的相關(guān)屬性。
關(guān)鍵代碼如下:
/* * 功能:構(gòu)造方法 * */ public DrawView(Context context, AttributeSet attrs) { super(context, attrs); view_width=context.getResources().getDisplayMetrics().widthPixels;//獲取屏幕寬度 view_height=context.getResources().getDisplayMetrics().heightPixels;//獲取屏幕高度 //創(chuàng)建一個(gè)與該View相同大小的緩存區(qū) cacheBitmap=Bitmap.createBitmap(view_width,view_height,Config.ARGB_8888); cacheCanvas=new Canvas();//創(chuàng)建一個(gè)新的畫布 path=new Path(); //在cacheCanvas上繪制cacheBitmap cacheCanvas.setBitmap(cacheBitmap); paint=new Paint(Paint.DITHER_FLAG);//Paint.DITHER_FLAG防抖動的 paint.setColor(Color.RED); //設(shè)置畫筆風(fēng)格 paint.setStyle(Paint.Style.STROKE);//設(shè)置填充方式為描邊 paint.setStrokeJoin(Paint.Join.ROUND);//設(shè)置筆刷轉(zhuǎn)彎處的連接風(fēng)格 paint.setStrokeCap(Paint.Cap.ROUND);//設(shè)置筆刷的圖形樣式(體現(xiàn)在線的端點(diǎn)上) paint.setStrokeWidth(1);//設(shè)置默認(rèn)筆觸的寬度為1像素 paint.setAntiAlias(true);//設(shè)置抗鋸齒效果 paint.setDither(true);//使用抖動效果 }
在DrawView類的onDraw()方法中,添加以下代碼,用于設(shè)置背景顏色、繪制cacheBitmap、繪制路徑以及保存當(dāng)前繪圖狀態(tài)到棧中,并調(diào)用restore()方法恢復(fù)所保存的狀態(tài),關(guān)鍵代碼如下:
/* * 功能:重寫onDraw方法 * */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(0xFFFFFFFF);//設(shè)置背景色 Paint bmpPaint=new Paint();//采用默認(rèn)設(shè)置創(chuàng)建一個(gè)畫筆 canvas.drawBitmap(cacheBitmap, 0, 0,bmpPaint);//繪制cacheBitmap canvas.drawPath(path, paint);//繪制路徑 canvas.save(Canvas.ALL_SAVE_FLAG);//保存canvas的狀態(tài) //恢復(fù)canvas之前保存的狀態(tài),防止保存后對canvas執(zhí)行的操作對后續(xù)的繪制有影響 canvas.restore(); }
在Draw類中,重寫onTouchEvent()方法,為該視圖添加觸摸事件監(jiān)聽器,在該方法中,首先獲取觸摸事件發(fā)生的位置,然后用switch語句對事件的不同狀態(tài)添加響應(yīng)代碼,最后調(diào)用invalidate()方法更新視圖。具體代碼如下:
@Override public boolean onTouchEvent(MotionEvent event) { //獲取觸摸事件發(fā)生的位置 float x=event.getX(); float y=event.getY(); switch(event.getAction()){ case MotionEvent.ACTION_DOWN: //將繪圖的起始點(diǎn)移到(x,y)坐標(biāo)點(diǎn)的位置 path.moveTo(x, y); preX=x; preY=y; break; case MotionEvent.ACTION_MOVE: //保證橫豎繪制距離不能超過625 float dx=Math.abs(x-preX); float dy=Math.abs(y-preY); if(dx>5||dy>5){ //.quadTo貝塞爾曲線,實(shí)現(xiàn)平滑曲線(對比lineTo) //x1,y1為控制點(diǎn)的坐標(biāo)值,x2,y2為終點(diǎn)的坐標(biāo)值 path.quadTo(preX, preY, (x+preX)/2, (y+preY)/2); preX=x; preY=y; } break; case MotionEvent.ACTION_UP: cacheCanvas.drawPath(path, paint);//繪制路徑 path.reset(); break; } invalidate(); return true;//返回true,表明處理方法已經(jīng)處理該事件 }
編寫clear()方法,用于實(shí)現(xiàn)橡皮擦功能,具體代碼如下:
public void clear(){ //設(shè)置圖形重疊時(shí)的處理方式 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); //設(shè)置筆觸的寬度 paint.setStrokeWidth(50); }
編寫保存當(dāng)前繪圖的save方法,在該方法中,調(diào)用saveBitmap()方法將當(dāng)前繪圖保存為PNG圖片。save()方法的具體代碼如下:
public void save(){ try{ saveBitmap("myPitcture"); }catch(IOException e){ e.printStackTrace(); } }
編寫保存繪制好的位圖的方法saveBitmap(),在該方法中,首先在SD卡上創(chuàng)建一個(gè)文件,然后創(chuàng)建一個(gè)文件輸出流對象,并調(diào)用Bitmap類的compress()方法將繪圖內(nèi)容壓縮為PNG格式輸出到剛剛創(chuàng)建的文件輸出流對象中,最后將緩沖區(qū)的數(shù)據(jù)全部寫出到輸出流中,并關(guān)閉文件輸出流對象。saveBitmap()方法的具體代碼如下:
private void saveBitmap(String fileName) throws IOException { File file=new File(getSDPath()+fileName+".png"); file.createNewFile(); FileOutputStream fileOS=new FileOutputStream(file); //將繪圖內(nèi)容壓縮為PNG格式輸出到輸出流對象中 cacheBitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOS); fileOS.flush();//將緩沖區(qū)中的數(shù)據(jù)全部寫出到輸出流中 fileOS.close();//關(guān)閉文件輸出流對象 } //獲得SD卡的根目錄 public String getSDPath(){ File sdDir = null; boolean sdCardExist = Environment.getExternalStorageState() .equals(android.os.Environment.MEDIA_MOUNTED); //判斷sd卡是否存在 if (sdCardExist) //如果SD卡存在,則獲取跟目錄 { sdDir = Environment.getExternalStorageDirectory();//獲取跟目錄 } return sdDir.toString(); }
在程序中需要向SD卡上保存文件,那么需要在AndroidManifest.xml文件中賦予相應(yīng)的權(quán)限,
具體代碼入下:
在res目錄中,創(chuàng)建一個(gè)menu目錄,并在該目錄中創(chuàng)建一個(gè)名稱為toolsmenu.xml的菜單資源文件,在該文件中編寫實(shí)例中所應(yīng)用的功能菜單,關(guān)鍵代碼如下:
其中values/strings.xml中:
test Hello world! Settings 畫筆顏色 紅色 綠色 藍(lán)色 畫筆寬度 細(xì) 中 粗 擦除繪畫 保存繪畫
在默認(rèn)創(chuàng)建的MainActivity中,為實(shí)例添加選項(xiàng)菜單。
首先,重寫onCreatOptionsMenu()方法,在該方法中,實(shí)例化一個(gè)MenuInflater對象,并調(diào)用該對象的inflate方法解析toolsmenu.xml的菜單資源文件。具體代碼如下:
/* * 創(chuàng)建選項(xiàng)菜單 * */ @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflator=new MenuInflater(this); inflator.inflate(R.menu.toolsmenu, menu); return super.onCreateOptionsMenu(menu); }
然后,重寫onOptionsItemSelected方法,分別對各個(gè)菜單項(xiàng)被選擇時(shí)做出相應(yīng)的處理,具體代碼如下:
/* * 當(dāng)菜單項(xiàng)被選擇時(shí),做出相應(yīng)的處理 * */ @Override public boolean onOptionsItemSelected(MenuItem item) { //獲取自定義的繪圖視圖 DrawView dv=(DrawView)findViewById(R.id.drawView1); dv.paint.setXfermode(null);//取消擦除效果 dv.paint.setStrokeWidth(1);//初始化畫筆的寬度 switch(item.getItemId()){ case R.id.red: dv.paint.setColor(Color.RED);//設(shè)置筆的顏色為紅色 item.setChecked(true); break; case R.id.green: dv.paint.setColor(Color.GREEN);//設(shè)置筆的顏色為綠色 item.setChecked(true); break; case R.id.blue: dv.paint.setColor(Color.BLUE);//設(shè)置筆的顏色為藍(lán)色 item.setChecked(true); break; case R.id.width_1: dv.paint.setStrokeWidth(1);//設(shè)置筆觸的寬度為1像素 break; case R.id.width_2: dv.paint.setStrokeWidth(5);//設(shè)置筆觸的寬度為5像素 break; case R.id.width_3: dv.paint.setStrokeWidth(10);//設(shè)置筆觸的寬度為10像素 break; case R.id.clear: dv.clear();//擦除繪畫 break; case R.id.save: dv.save();//保存繪畫 break; } return true; }
關(guān)于Android中怎么實(shí)現(xiàn)一個(gè)繪圖板問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識。