温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

怎么在Android中实现撤销反撤销功能

发布时间:2021-05-22 16:50:50 来源:亿速云 阅读:551 作者:Leah 栏目:移动开发

这篇文章给大家介绍怎么在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是什么

Android是一种基于Linux内核的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由美国Google公司和开放手机联盟领导及开发。

关于怎么在Android中实现撤销反撤销功能就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI