您好,登錄后才能下訂單哦!
這篇文章給大家介紹怎么在Android中實現撤銷反撤銷功能,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
首先,需要一個bean類存儲每一筆的數據,這里定義一個PaintData,里面需要定義個draw方法,因為撤銷的時候,需要重新繪制。
data class PaintData( var mPaint: Paint, //保存畫筆 var mPath: Path //保存路徑 ) { /** * 撤銷和反撤銷之后 重新繪制 * @param canvas 繪制的畫布 */ fun draw(canvas: Canvas){ canvas.drawPath(mPath,mPaint) } }
2.2 修改清空畫板方法
因為多了列表,所以清空畫板的方法需要把列表也清除了
/** * 清空畫布 * @param isClearList 時候清空數據列表 */ fun clear(isClearList:Boolean) { if(isClearList){ mRevokedList.clear() mPaintedList.clear() } mBufferCanvas.drawColor(0, PorterDuff.Mode.CLEAR) invalidate() }
2.3 實現撤銷方法
在view定義兩個列表,一個是已經畫的內容列表,一個是撤銷內容的列表
//儲存已經寫的筆畫 private var mPaintedList: MutableList<PaintData> = ArrayList<PaintData>() //已經撤銷的列表 private var mRevokedList: MutableList<PaintData> = ArrayList<PaintData>()
添加固話層canvas和bitmap,超出記錄的畫筆就寫死在固化層了
//固化層,超出最大筆畫就先繪制到這個層 private lateinit var mHoldBitmap: Bitmap private lateinit var mHoldCanvas: Canvas //最多記錄20畫筆跡 private val MAX_PAINT_RECORED = 20 //在測量的時候進行初始化: override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { if(mBufferCanvas == null){ mBufferBitmap = Bitmap.createBitmap(measuredWidth, measuredHeight, Bitmap.Config.ARGB_8888) //canvas繪制的內容,將會在這個mBufferBitmap內 mBufferCanvas = Canvas(mBufferBitmap) } if(mHoldCanvas == null){ mHoldBitmap = Bitmap.createBitmap(measuredWidth, measuredHeight, Bitmap.Config.ARGB_8888) mHoldCanvas = Canvas(mHoldBitmap) } }
然后定義撤回的方法
/** * 撤回一個筆跡 * @return 是否撤回成功 */ fun revoked(){ reDraw(mPaintedList) }
反撤銷方法基本一致,只是改了個列表:
/** * 反撤回一個筆跡 */ fun unRevoked(){ reDraw(mRevokedList) }
然后重新繪制的方法為:
/** * 重新繪制 * @param paintList 需要操作的list */ private fun reDraw(paintList:MutableList<PaintData>){ if(paintList.size > 0){ val paint = paintList.removeAt(paintList.size-1) if(paintList === mPaintedList){ mRevokedList.add(paint) }else{ mPaintedList.add(paint) } //清空緩存畫板 mBufferCanvas.drawColor(0, PorterDuff.Mode.CLEAR) invalidate() } }
然后就是畫筆的保存,在觸摸按下的時候,進行畫筆的保存
override fun onTouchEvent(event: MotionEvent): Boolean { when(event.action){ MotionEvent.ACTION_DOWN -> { //手指按下的時候 //將起始點移動到當前坐標 mPath.moveTo(event.x,event.y) //記錄上次觸摸的坐標,注意ACTION_DOWN方法只會執行一次 preX = event.x preY = event.y //保存畫筆 mPaintedList.add(PaintData(Paint(mPaint),Path(mPath))) } MotionEvent.ACTION_MOVE -> { //手指移動的時候 //繪制圓滑曲線,即貝塞爾曲線,貝塞爾曲線這個知識自行了解 mPaintedList.get(mPaintedList.size-1).mPath.quadTo(preX,preY,event.x,event.y) //重新繪制,會調用onDraw方法 invalidate() preX = event.x preY = event.y } MotionEvent.ACTION_UP ->{ //清除路徑的內容 mPath.reset() } } // true:告訴系統,這個觸摸事件由我來處理 // false:告訴系統,這個觸摸事件我不處理,這時系統會把觸摸事件傳遞給imageview的父節點 return true }
最后繪制的時候:
override fun onDraw(canvas: Canvas) { super.onDraw(canvas) //超出緩存的就固化到緩存bitmap while(mPaintedList.size > MAX_PAINT_RECORED){ val paintData = mPaintedList.removeAt(0) paintData.draw(mHoldCanvas) } //繪制固化的內容到緩存Canvas mBufferCanvas.drawBitmap(mHoldBitmap,0f,0f,null) //繪制記錄的畫筆 for(paint in mPaintedList){ //重新繪制每個path paint.draw(mBufferCanvas) } //畫出緩存bitmap的內容 canvas.drawBitmap(mBufferBitmap,0f,0f,null) }
最后清除畫布的時候,需要把畫筆列表也清除了:
/** * 清空畫布 */ fun clear() { mRevokedList.clear() mPaintedList.clear() mHoldCanvas.drawColor(0, PorterDuff.Mode.CLEAR) mBufferCanvas.drawColor(0, PorterDuff.Mode.CLEAR) invalidate() }
Android是一種基于Linux內核的自由及開放源代碼的操作系統,主要使用于移動設備,如智能手機和平板電腦,由美國Google公司和開放手機聯盟領導及開發。
關于怎么在Android中實現撤銷反撤銷功能就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。