Android图形图像之自定义控件属性(demo:刮刮乐与打码以及图片

概述:

此部分内容涉及到android的自定义View、自定义属性和Android图形图像处理的综合应用:Bitmap、Path、Matrix、Canvas。 图片打码以及如何缓存打码后的图片都是日常极有可能用到的,而刮图也并不是用不到。 下面的demo写的是一个的刮刮乐例程,里面涉及到如何自定义控件属性,以及如何存储处理后的图片,注释很详细,看注释即可。 结果演示:

文件保存后的结果:

Demo

新建一个自定义View:

{private int width;private int height;private float x;private float y;private float old_x;private float old_y;private Paint mPaintCircle;private Paint mPaintRect;private Bitmap mBitmap;private Bitmap mBitmapGround;private Matrix matrix;private Path mPath;private Canvas mCanvasBm;public MyBitMapViewSec(Context context) {super(context);}(Context context, AttributeSet attrs) {//attrs是这个View在xml布局中的所有属性的集合super(context, attrs);//将attrs解析为TypedArray类的对象final TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.selfish);//得到xml中本自定义View的self_background属性的内容,并强制转换为BitmapDrawable类型BitmapDrawable dra = (BitmapDrawable) a.getDrawable(R.styleable.selfish_self_background);if(dra!=null){//如果dra不为空,就将dra赋值给mBitmapGroundmBitmapGround = dra.getBitmap();}else {//mBitmapGround里传入的是一张图片mBitmapGround = BitmapFactory.decodeResource(getResources(),R.mipmap.qingxin);}//得到xml中本自定义View的self_paintWidth属性中的内容,如果得不到就给个默认值30float paintWidth = a.getDimension(R.styleable.selfish_self_paintWidth,30);mPaintCircle = new Paint();mPaintCircle.setColor(Color.YELLOW);mPaintRect = new Paint();//XOR:交叠和被交叠部分均不显示;DST_OVER:自身交叠部分不显示;SRC_OVER交叠部分只显示自己PorterDuffXfermode mode = new PorterDuffXfermode(PorterDuff.Mode.XOR);mPaintRect.setXfermode(mode);mPaintRect.setStrokeWidth(paintWidth);mPaintRect.setStrokeJoin(Paint.Join.ROUND);//设置联接部分样式mPaintRect.setStrokeCap(Paint.Cap.ROUND);//设置中间部分样式:圆形mPaintRect.setStyle(Paint.Style.FILL_AND_STROKE);mPath = new Path();matrix = new Matrix();}(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);setMeasuredDimension(width, height);//这一句不能放到构造方法中,是因为还没有得到width和height的值mBitmap = Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_8888);mCanvasBm = new Canvas(mBitmap);//自定义一个画布,画布材料是Bitmap对象}(Canvas canvas) {super.onDraw(canvas);matrix.reset();//下面两行的作用是放大图片,并绘制出来matrix.postScale((float)width/mBitmapGround.getWidth(),(float)height/mBitmapGround.getHeight());canvas.drawBitmap(mBitmapGround,matrix,null);//画一个蒙板mCanvasBm.drawRect(0,0,width,height,mPaintCircle);//将path画出,因为mPaintRect的模式为PorterDuff.Mode.XOR,所以画图时会让交叠部分都不显示,从而显示出底部图片来mCanvasBm.drawPath(mPath,mPaintRect);//这一步的意义是:将mCanvasBm在mBitmap上绘制的内容画出canvas.drawBitmap(mBitmap,0,0,null);}(MotionEvent event) {switch (event.getAction()){case MotionEvent.ACTION_DOWN:y = event.getY();x = event.getX();//CW是Path移动方向:顺时针//mPath.addCircle(x,y,50,Path.Direction.CW);mPath.moveTo(x,y);//重新绘制,就是重新调用onDraw()方法invalidate();//更新old_x、old_y的值old_x = x;old_y = y;return true;case MotionEvent.ACTION_MOVE:y = event.getY();x = event.getX();//将mPath移动到上一个位置mPath.moveTo(old_x, old_y);//绘制贝塞尔曲线,((x + old_x) / 2, (y + old_y) / 2)作为控制点,(x, y)作为结束点mPath.quadTo((x + old_x) / 2, (y + old_y) / 2, x, y);invalidate();old_x = x;old_y = y;return true;}return super.onTouchEvent(event);}}

如果用的是android studio,在res/value路径下新建一个文件,命名随意,我这里叫selfish,内容如下:

==>=></resources>

上面的打码中:attr代表我的自定View的属性,我这里添加了两个属性;declare-styleabl是给自定义控件添加自定义属性用的,它是一个属性集。

发光并非太阳的专利,你也可以发光

Android图形图像之自定义控件属性(demo:刮刮乐与打码以及图片

相关文章:

你感兴趣的文章:

标签云: