android canvas镜像,Android 高级UI9 Canvas save和restore的使用

自己定义控件时经常遇到重写View的draw()方法,draw()方法经常设计到save()和restore()这两个方法.这两个相互匹配出现的,作用是用来保存画布的状态和取出保存的状态的。

save():用来保存canvas的状态,save()方法之后的代码,能够调用canvas的平移、放缩、旋转、裁剪等操作!

restore():用来恢复canvas之前保存的状态,防止save()方法代码之后对canvas运行的操作。继续对兴许的绘制会产生影响。通过该方法能够避免连带的影响!

public class MyView extends View {

public MyView(Context context) {

super(context);

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

canvas.drawColor(Color.GREEN);

//canvas变换操作不会对前面造成影响

canvas.clipRect(new Rect(100, 200, 500, 500));

canvas.drawColor(Color.BLUE);

}

}

bc6d077cc597

canvas.drawColor(Color.GREEN);

//canvas变换操作不会对前面造成影响

canvas.clipRect(new Rect(100, 200, 500, 500));

canvas.drawColor(Color.BLUE);

Paint paint = new Paint();

paint.setColor(Color.RED);

canvas.drawCircle(200,200,500,paint);

bc6d077cc597

我们发现canvas裁剪产生的画布,绘制,不会对非裁剪的区域造成影响。

canvas.drawColor(Color.GREEN);

//保存画布当前的状态(保存到画布栈里面了)

canvas.save();

//canvas变换操作不会对前面造成影响

canvas.clipRect(new Rect(100, 100, 500, 500));

canvas.drawColor(Color.BLUE);

//恢复画布

canvas.restore();

Paint paint = new Paint();

paint.setColor(Color.RED);

canvas.drawCircle(100, 100, 100, paint);

bc6d077cc597

canvas.drawColor(Color.GREEN);

//保存画布当前的状态

canvas.save();

//canvas变换操作不会对前面造成影响

canvas.clipRect(new Rect(100, 100, 500, 500));

canvas.drawColor(Color.BLUE);

canvas.save();

//恢复画布

//canvas.restore();

Paint paint = new Paint();

paint.setColor(Color.RED);

canvas.drawCircle(100, 100, 100, paint);

canvas.restore();

paint.setColor(Color.YELLOW);

canvas.drawCircle(150,150,100,paint);

bc6d077cc597

结论:画板是以栈的形式进行存储

搜索动画实际案例

public abstract class BaseController {

public static final int STATE_ANIM_NONE = 0;

public static final int STATE_ANIM_START = 1;

public static final int STATE_ANIM_STOP = 2;

public static final int DEFAULT_ANIM_TIME = 5000;

public static final float DEFAULT_ANIM_STARTF = 0;

public static final float DEFAULT_ANIM_ENDF = 1;

private MySearchView mySearchView;

public int mState = STATE_ANIM_NONE;

public abstract void draw(Canvas canvas,Paint paint);

public void startAnim(){

}

public void resetAnim(){

}

public int getWidth(){

return mySearchView.getWidth();

}

public int getHeight(){

return mySearchView.getHeight();

}

public void setSearchView(MySearchView mySearchView){

this.mySearchView = mySearchView;

}

public float mpro = -1;

public ValueAnimator startViewAnimation(){

ValueAnimator valueAnimator = ValueAnimator.ofFloat(0,1);

valueAnimator.setDuration(800L);

valueAnimator.setInterpolator(new LinearInterpolator());

valueAnimator.addUpdateListener(new AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

mpro = (float) animation.getAnimatedValue();

mySearchView.invalidate();

}

});

valueAnimator.start();

mpro = 0;

return valueAnimator;

}

}

绘制类

public class Controller1 extends BaseController {

private String mColor = "#4CAF50";

private int cx, cy, cr;

private RectF mRectF;

private int j = 15;

public Controller1() {

mRectF = new RectF();

}

@Override

public void draw(Canvas canvas, Paint paint) {

canvas.drawColor(Color.parseColor(mColor));

switch (mState) {

case STATE_ANIM_NONE:

drawNormalView(paint, canvas);

break;

case STATE_ANIM_START:

drawStartAnimView(paint, canvas);

break;

case STATE_ANIM_STOP:

// drawNormalView(paint, canvas);

drawStopAnimView(paint, canvas);

break;

}

}

private void drawStopAnimView(Paint paint, Canvas canvas) {

}

private void drawStartAnimView(Paint paint, Canvas canvas) {

canvas.save();

//0~1

if (mpro <= 0.5f) {

/**

* 绘制圆和把手

*/

/**

*

* -360 ~ 0 需要变换的范围

* 0 ~ 0.5 实际的变化范围

* 转换公式:360*(mpro*2-1)

*/

canvas.drawArc(

mRectF,

45,

360 * (mpro * 2 - 1),

false,

paint);

canvas.drawLine(

mRectF.right - j,

mRectF.bottom - j,

mRectF.right + cr - j,

mRectF.bottom + cr - j,

paint);

} else {

/**

* 绘制圆和把手

*/

canvas.drawLine(

mRectF.right - j + cr * (mpro * 2 - 1),

mRectF.bottom - j + cr * (mpro * 2 - 1),

mRectF.right - j + cr,

mRectF.bottom + cr - j,

paint);

}

canvas.drawLine(

(mRectF.right - j + cr) * (1 - mpro * 0.8f),

mRectF.bottom + cr - j,

mRectF.right - j + cr,

mRectF.bottom + cr - j,

paint);

canvas.restore();

mRectF.left = cx - cr + mpro * 250;

mRectF.right = cx + cr + mpro * 250;

mRectF.top = cy - cr;

mRectF.bottom = cy + cr;

}

private void drawNormalView(Paint paint, Canvas canvas) {

cr = getWidth() / 20;

cx = getWidth() / 2;

cy = getHeight() / 2;

mRectF.left = cx - cr;

mRectF.right = cx + cr;

mRectF.top = cy - cr;

mRectF.bottom = cy + cr;

canvas.save();

paint.reset();

paint.setAntiAlias(true);

paint.setColor(Color.WHITE);

paint.setStrokeWidth(5);

paint.setStyle(Paint.Style.STROKE);

canvas.rotate(45, cx, cy);

canvas.drawLine(cx + cr, cy, cx + cr * 2, cy, paint);

// canvas.drawArc(

// mRectF,

// 0, //起始角度,相对X轴正方向

// 360, //画多少角度的弧度

// false, //boolean,false :只用一个弧度线;true:闭合的边

// paint);

// canvas.restore();

canvas.drawArc(

mRectF,

0,

360,

false,

paint);

canvas.restore();

}

@Override

public void startAnim() {

super.startAnim();

mState = STATE_ANIM_START;

startViewAnimation();

}

@Override

public void resetAnim() {

// TODO Auto-generated method stub

super.resetAnim();

mState = STATE_ANIM_STOP;

startViewAnimation();

}

}

public class MySearchView extends View {

private Paint mPaint;

private BaseController mController;

public MySearchView(Context context) {

super(context);

}

public MySearchView(Context context,

@Nullable AttributeSet attrs) {

super(context, attrs);

init();

}

private void init() {

mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

mPaint.setStrokeWidth(5);

}

public void setController(BaseController controller) {

this.mController = controller;

mController.setSearchView(this);

invalidate();

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

mController.draw(canvas,mPaint);

}

public void startAnimation(){

if(mController!=null){

mController.startAnim();

}

}

public void resetAnimation(){

if(mController!=null){

mController.resetAnim();

}

}

}

public class MainActivity extends AppCompatActivity {

private MySearchView searchView;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

searchView = (MySearchView) findViewById(R.id.sv);

searchView.setController(new Controller1());

}

public void start(View view) {

searchView.startAnimation();

}

public void reset(View view) {

searchView.resetAnimation();

}

}

bc6d077cc597

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值