麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 系統 > Android > 正文

Android畫板開發之撤銷反撤銷功能

2019-10-21 21:32:36
字體:
來源:轉載
供稿:網友

一、分析

這篇將會講解撤銷反撤銷功能的實現,先討論一下這個原理是怎么樣實現的。

每次撤回的內容,內容是怎么定義呢? 其實就是每一筆,每一筆作為撤回的內容,那每一筆怎么算呢,就是算手指從按下-移動-放開這一個過程就是一筆。

我們只需記錄這個過程為一筆,然后用一個已畫列表list列表來記錄這個過程的paint畫筆和路徑path。

撤銷的時候就把后面的一個數據移到另一個撤銷列表

反撤銷的時候,就把撤銷列表的最后面那條數據移動到已畫列表。

然后,還有一個重點,就是畫筆的保存數量,上面說記錄每一筆畫筆,這當然是有個限度,不可能畫了好幾百筆都記錄下來,這樣子內存消耗很大的,所以超出顯示畫筆數量的時候,我們就把以前的畫死在畫板上。

Android,畫板,撤銷,反撤銷

基本原理是這樣子的。接下來跟著我實現

二、實現

如何實現撤回功能

2.1 定義數據類

首先,需要一個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: Bitmapprivate 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()  }

重點就是在于利用一個bean類來保存每筆的 畫筆和路徑,然后撤銷時候重新繪制。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 一级毛片免费观看在线 | 国产正在播放 | 蜜桃传媒视频麻豆第一区免费观看 | 久久国产一级片 | 操操插插 | 国产免费一区二区三区 | 国产成人强伦免费视频网站 | 免费在线观看午夜视频 | 色淫网站免费视频 | 中国杭州少妇xxxx做受 | 欧美亚洲国产成人 | 成人午夜免费网站 | 国产一区二区欧美 | 久久午夜免费视频 | 日韩av成人 | 国产自91精品一区二区 | 92自拍视频 | 黄色毛片视频在线观看 | 国产一区二区欧美 | 手机在线看片国产 | 久久爽久久爽久久av东京爽 | 末成年女av片一区二区 | 亚洲男人一区 | 欧美精品网址 | 99re色| 黄色av免费网站 | 欧美a∨一区二区三区久久黄 | 美女黄影院 | 亚洲免费在线视频 | 久久综合九色综合久久久精品综合 | 轻点插视频 | 久久免费视频一区二区三区 | 国产精品99久久久久久久女警 | 激情福利视频 | 久草在线综合 | 毛片电影在线看 | 成人短视频在线观看免费 | 久久经典 | 黄色免费小视频网站 | 人人玩人人爽 | 福利一区二区三区视频在线观看 |