invalidate()函数的区域更新例子

public class FingerView extends View {

  private static final float STROKE_WIDTH = 5f;

  /** Need to track this so the dirty region can accommodate the stroke. **/
  private static final float HALF_STROKE_WIDTH = STROKE_WIDTH / 2;

  private Paint paint = new Paint();
  private Path path = new Path();

  /**
   * Optimizes painting by invalidating the smallest possible area.
   */
  private float lastTouchX;
  private float lastTouchY;
  private final RectF dirtyRect = new RectF();

  public FingerView (Context context, AttributeSet attrs) {
    super(context, attrs);

    paint.setAntiAlias(true);
    paint.setColor(Color.BLACK);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeJoin(Paint.Join.ROUND);
    paint.setStrokeWidth(STROKE_WIDTH);
  }

  /**
   * Erases the signature.
   */
  public void clear() {
    path.reset();

    // Repaints the entire view.
    invalidate();
  }

  @Override
  protected void onDraw(Canvas canvas) {
    canvas.drawPath(path, paint);
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    float eventX = event.getX();
    float eventY = event.getY();

    switch (event.getAction()) {
      case MotionEvent.ACTION_DOWN:
        path.moveTo(eventX, eventY);
        lastTouchX = eventX;
        lastTouchY = eventY;
        // There is no end point yet, so don't waste cycles invalidating.
        return true;

      case MotionEvent.ACTION_MOVE:
      case MotionEvent.ACTION_UP:
        // Start tracking the dirty region.
        resetDirtyRect(eventX, eventY);

        // When the hardware tracks events faster than they are delivered, the
        // event will contain a history of those skipped points.
        int historySize = event.getHistorySize();
        for (int i = 0; i < historySize; i++) {
          float historicalX = event.getHistoricalX(i);
          float historicalY = event.getHistoricalY(i);
          expandDirtyRect(historicalX, historicalY);
          path.lineTo(historicalX, historicalY);
        }

        // After replaying history, connect the line to the touch point.
        path.lineTo(eventX, eventY);
        break;

      default:
        debug("Ignored touch event: " + event.toString());
        return false;
    }

    // Include half the stroke width to avoid clipping.
    invalidate(
        (int) (dirtyRect.left - HALF_STROKE_WIDTH),
        (int) (dirtyRect.top - HALF_STROKE_WIDTH),
        (int) (dirtyRect.right + HALF_STROKE_WIDTH),
        (int) (dirtyRect.bottom + HALF_STROKE_WIDTH));
    
    lastTouchX = eventX;
    lastTouchY = eventY;

    return true;
  }

  /**
   * Called when replaying history to ensure the dirty region includes all
   * points.
   */
  private void expandDirtyRect(float historicalX, float historicalY) {
    if (historicalX < dirtyRect.left) {
      dirtyRect.left = historicalX;
    } else if (historicalX > dirtyRect.right) {
      dirtyRect.right = historicalX;
    }
    if (historicalY < dirtyRect.top) {
      dirtyRect.top = historicalY;
    } else if (historicalY > dirtyRect.bottom) {
      dirtyRect.bottom = historicalY;
    }
  }

  /**
   * Resets the dirty region when the motion event occurs.
   */
  private void resetDirtyRect(float eventX, float eventY) {

    // The lastTouchX and lastTouchY were set when the ACTION_DOWN
    // motion event occurred.
    dirtyRect.left = Math.min(lastTouchX, eventX);
    dirtyRect.right = Math.max(lastTouchX, eventX);
    dirtyRect.top = Math.min(lastTouchY, eventY);
    dirtyRect.bottom = Math.max(lastTouchY, eventY);
  }
}


前面讲过androidui高性能布局里面在invalidate的时候进行区域更新性能更好,这里给出一个例子。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值