移动互联网开发教学案例学习-7

2021SC@SDUSC

目录

案例——draw_compare

MSurfaceView类——SurfaceView基本框架

重写run()方法

 doDraw()方法

draw()方法

surfaceCreate()方法重写

surfaceDestoryed()方法重写

onSizeChanged()方法重写

 reset()方法

getBitmap()方法

changePic()方法


案例——draw_compare

MSurfaceView类——SurfaceView基本框架

重写run()方法

在该方法中,获取开始和结束的时间,如果处于mIsDrawing状态,则调用draw()方法,如果开始和结束时间差<100,则要让线程睡眠到100.

    @Override
    public void run() {
        //获取画布

        long start = System.currentTimeMillis();
        while (mIsDrawing) {
            //画
            draw();
        }
        long end = System.currentTimeMillis();
        //解锁画布

        if (end - start < 100) {
            try {
                Thread.sleep(100 - (end - start));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

 doDraw()方法

    private void doDraw(Canvas canvas) {
        try {
//            mCanvas = mHolder.lockCanvas();
            if (canvas != null) {
                canvas.drawPath(mPath, mPaint);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

drawPath(Path path, Paint paint) 这个方法是通过描述路径的方式来绘制图形的,它的 path 参数就是用来描述图形路径的对象。

draw()方法

    private void draw() {
        try {
            //获得锁
            mCanvas = mHolder.lockCanvas();
            if (mCanvas != null) {
                //画背景
                mCanvas.drawBitmap(mBg,null,mDrawPictureRect,null);
//               mCanvas.drawColor(Color.WHITE);
                //画线
                mCanvas.drawPath(mPath, mPaint);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (mCanvas != null) {
                //释放锁
                mHolder.unlockCanvasAndPost(mCanvas);
            }
        }
    }

abstract Canvas lockCanvas(),获取Surface中的Canvas对象,并锁定之。

draw()方法中先是进行Canvas对象锁的获取,如果Surface中已经有Canvas对象,则进行背景的绘制,在进行画线操作,然后解锁Canvas画布。

surfaceCreate()方法重写

如果处于isDrawing状态,则开启线程。

  @Override
    public void surfaceCreated(SurfaceHolder arg0) {
        mIsDrawing = true;
        new Thread(this).start();
    }

surfaceDestoryed()方法重写

在销毁时发生,在这里将画面的线程停止、释放。

    @Override
    public void surfaceDestroyed(SurfaceHolder arg0) {
        mIsDrawing = false;

    }

onSizeChanged()方法重写

该方法进行尺寸改变时的操作

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = w;
        mHeight = h;
        mDrawPictureRect.set(0, 0, w, h);
    }

 reset()方法

用于清楚path

   public void reset() {
        Log.e("TAG","CLEAR");
        mPath.reset();
    }

getBitmap()方法

    public Bitmap getBitmap() {
        Log.e("mWidth", "" + mWidth);
        Log.e("mHeight", "" + mHeight);
        Bitmap bitmap = Bitmap.createBitmap(this.getWidth(), this.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        canvas.drawColor(Color.WHITE);
        doDraw(canvas);
//        canvas.save();

        return bitmap;
    }

Bitmap.Config有以下几个常量:

public static final Bitmap.Config  ALPHA_8
public static final Bitmap.Config  ARGB_4444 
public static final Bitmap.Config  ARGB_8888
public static final Bitmap.Config  RGB_565

这些是色彩的存储方法:ARGB指的是一种 色彩模式,里面A代表Alpha,R表示red,G表示green,B表示blue.

其实所有的可见色都是右红绿蓝组成的,所以红绿蓝又称为三原色,每个原色都存储着所表示颜色的信息值。

ALPHA_8就是Alpha由8位组成
ARGB_4444就是由4个4位组成即16位
ARGB_8888就是由4个8位组成即32位
RGB_565就是R为5位,G为6位,B为5位共16位

ALPHA_8——代表8位Alpha位图

ARGB_4444——代表16位ARGB位图

ARGB_8888——代表32位ARGB位图

RGB_565——代表8位RGB位图

位图位数越高代表其可以存储的颜色信息越多,当然图像也就越逼真。

changePic()方法

    public void changePic(){
        reset();
        Random random=new Random();
        int index=random.nextInt(drawable_list.size());
        draw=drawable_list.get(index);
        initBitmaps();
    }

该方法用于改变背景图。通过random.nextInt(drawable_list.size())生成0~drawable_list.size()(不包括右侧)随机数的方式从drawable_list中选择一个整数,再通过initBitmaps()中调用loadImageByResId(int resId)方法来初始化新的背景图。

    private Bitmap loadImageByResId(int resId) {
        return BitmapFactory.decodeResource(getResources(), resId);
    }

public static Bitmap decodeResource (Resources res, int id, BitmapFactory.Options opts)

  • res     包含图像数据的资源对象
  • id  图像数据的资源的id
  • opts    可以为空,控制采样率和实付图像完全被解码的选项,或者仅仅返回大小
  • 返回值

使用Bitmap bm = BitmapFactory.decodeResource(context.getResources(), resId);

通过 bm.getWidth() 和 bm.getHeight() 来获取宽和高;

还有更好的方法:

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(context.getResources(), resId, options);

通过 options.outWidth 和 options.outHeight来获取宽和高,这种方法更节省内存。防止oom问题。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值