博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android bitmap 描边,Android 绘图之Canvas相关API使用
阅读量:6815 次
发布时间:2019-06-26

本文共 15178 字,大约阅读时间需要 50 分钟。

Android 自定义控件或多或少都会用到Canvas,那么我们就需要熟悉它的API。Canvas给我们提供了大量的的DrawXXX方法,通过这些方法我们就可以绘制出我们想要的效果。接下来看看官方是怎么说的:

The Canvas class holds the "draw" calls. To draw something, you need 4 basic components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing into the bitmap), a drawing primitive (e.g. Rect, Path, text, Bitmap), and a paint (to describe the colors and styles for the drawing).

大致意思就是说:

Canvas类持有“draw”调用。 要绘制一些东西,你需要4个基本组件:一个位图来保存像素,一张画布(Canvas)来主持绘图调用(写入位图),一个绘图图元(如Rect,Path,text,Bitmap)和一支画笔(描述绘图的颜色和样式)。

首先介绍下画笔(Paint)的常用API:

private void initPaint() {

// 设置最基本的属性

// 设置画笔颜色

// 可直接引入Color类,如Color.red等

mPaint.setColor(int color);

// 设置画笔模式

mPaint.setStyle(Style style);

// Style有3种类型:

// 类型1:Paint.Style.FILLANDSTROKE(描边+填充)

// 类型2:Paint.Style.FILL(只填充不描边)

// 类型3:Paint.Style.STROKE(只描边不填充)

//设置画笔的粗细

mPaint.setStrokeWidth(float width);

// 如设置画笔宽度为10px

mPaint.setStrokeWidth(10f);

// 不常设置的属性

// 得到画笔的颜色

mPaint.getColor();

// 设置Shader

// 即着色器,定义了图形的着色、外观

mPaint.setShader(Shader shader);

//设置画笔的a,r,p,g值

mPaint.setARGB(int a, int r, int g, int b);

//设置透明度

mPaint.setAlpha(int a);

//得到画笔的Alpha值

mPaint.getAlpha();

// 对字体进行设置(大小、颜色)

//设置字体大小

mPaint.setTextSize(float textSize)

// 设置对齐方式

mPaint.setTextAlign(Algin algin);

// LEFT:左对齐

// CENTER:居中对齐

// RIGHT:右对齐

//设置文本的下划线

mPaint.setUnderlineText(boolean underlineText);

//设置文本的删除线

mPaint.setStrikeThruText(boolean strikeThruText);

//设置文本粗体

mPaint.setFakeBoldText(boolean fakeBoldText);

// 设置斜体

mPaint.setTextSkewX(-0.5f);

// 设置文字阴影

mPaint.setShadowLayer(5,5,5,Color.YELLOW);

}

Paint默认的字体大小为12px,在绘制文本时我们往往要考虑密度density设置合适的字体大小。画笔的默认颜色为黑色,默认的style为FILL,默认的cap为BUTT,默认的线宽为0。

一 坐标系

Canvas坐标系

Canvas坐标系即Canvas本身的坐标系。Canvas坐标原点(0,0)在View的左上角,向右为X轴正方向,向下为Y轴正方向。Canvas坐标系唯一且不会改变。

绘图坐标系

绘图坐标系区别于Canvas坐标系,以我们绘图起始点为坐标原点(0,0),绘图坐标系默认与Canvas坐标系重合。绘图坐标系原点位置可以更改,Canvas的 translate、rotate、scale 操作都是基于绘图坐标系变化。

//绘制坐标系

private void drawAxis(Canvas canvas) {

int width = canvas.getWidth();

int height = canvas.getHeight();

int translate = width / 5;

//设置画笔宽度

mPaint.setStrokeWidth(10);

//设置笔触样式

mPaint.setStrokeCap(Paint.Cap.ROUND);

//绘制默认绘图坐标系(此时与Canvas坐标系重合)

//绘制红色X轴

mPaint.setColor(Color.RED);

canvas.drawLine(0, 0, width, 0, mPaint);

//绘制蓝色Y轴

mPaint.setColor(Color.BLUE);

canvas.drawLine(0, 0, 0, height, mPaint);

//平移

canvas.translate(translate, translate);

//绘制平移后绘图坐标系

//绘制红色X轴

mPaint.setColor(Color.RED);

canvas.drawLine(0, 0, width, 0, mPaint);

//绘制蓝色Y轴

mPaint.setColor(Color.BLUE);

canvas.drawLine(0, 0, 0, height, mPaint);

//平移 旋转30度

canvas.translate(translate, translate);

canvas.rotate(30);

//绘制平移旋转后绘图坐标系

//绘制红色X轴

mPaint.setColor(Color.RED);

canvas.drawLine(0, 0, width, 0, mPaint);

//绘制蓝色Y轴

mPaint.setColor(Color.BLUE);

canvas.drawLine(0, 0, 0, height, mPaint);

}

二 Canvas绘制颜色

单一颜色填充Canvas画布

drawColor

drawRGB

drawARGB

//绘制画布颜色

private void drawCanvasColor(Canvas canvas) {

//drawARGB

canvas.drawARGB(255, 47, 140, 150);

}

三 绘制点

drawPoint 绘制点

drawPoints 绘制一组点

//绘制点

private void drawPoint(Canvas canvas) {

int width = canvas.getWidth();

int height = canvas.getHeight();

int translateY = height/5;

//设置画笔颜色

mPaint.setColor(Color.RED);

//设置画笔宽度

mPaint.setStrokeWidth(200);

//设置笔触样式

mPaint.setStrokeCap(Paint.Cap.BUTT);

//保存当前画布状态(坐标系)

canvas.save();

canvas.drawPoint(width / 3, height / 3, mPaint);

//恢复上次画布保存状态(坐标系)

canvas.restore();

mPaint.setStrokeCap(Paint.Cap.ROUND);

mPaint.setColor(Color.GREEN);

canvas.save();

canvas.translate(0, translateY);

canvas.drawPoint(width / 3, height / 3, mPaint);

canvas.restore();

mPaint.setStrokeCap(Paint.Cap.SQUARE);

mPaint.setColor(Color.BLUE);

canvas.save();

canvas.translate(translateY, translateY);

canvas.drawPoint(width / 3, height / 3, mPaint);

canvas.restore();

}

四 绘制线

drawLine 绘制线

drawLines 绘制一组线

//绘制线

private void drawLine(Canvas canvas) {

int width = canvas.getWidth();

int height = canvas.getHeight();

int startX = width / 5;

int startY = height / 5;

//设置画笔颜色

mPaint.setColor(Color.RED);

mPaint.setStrokeWidth(20);

//设置笔触样式

mPaint.setStrokeCap(Paint.Cap.BUTT);

//画笔触为BUTT的线

canvas.drawLine(startX, startY, width - startX, startY, mPaint);

//向下平移20

canvas.translate(0, 60);

mPaint.setColor(Color.GREEN);

mPaint.setStrokeCap(Paint.Cap.ROUND);

//画笔触为ROUND的线

canvas.drawLine(startX, startY, width - startX, startY, mPaint);

canvas.translate(0, 60);

mPaint.setColor(Color.BLUE);

mPaint.setStrokeCap(Paint.Cap.SQUARE);

//画笔触为SQUARE的线

canvas.drawLine(startX, startY, width - startX, startY, mPaint);

canvas.translate(0, 80);

mPaint.setColor(Color.BLACK);

float[] pts = new float[]{startX, startY, width - startX, startY, startX, startY + 60, width - startX, startY + 60};

canvas.drawLines(pts, mPaint);

}

五 绘制矩形

drawRect 绘制矩形

drawRoundRect 绘制圆角矩形

//绘制矩形

private void drawRect(Canvas canvas) {

int width = canvas.getWidth();

int height = canvas.getHeight();

//设置画笔颜色

mPaint.setColor(Color.RED);

//设置画笔宽度

mPaint.setStrokeWidth(16);

//设置画笔样式

mPaint.setStyle(Paint.Style.FILL);

canvas.drawRect(20, 20, 400, 200, mPaint);

//绘制矩形 API21

//canvas.drawRoundRect(220, 220, 400, 400, 10, 10, mPaint);

RectF rect = new RectF(20, 420, 800, 600);

canvas.drawRoundRect(rect, 10, 10, mPaint);

mPaint.setColor(Color.BLUE);

mPaint.setStyle(Paint.Style.STROKE);

canvas.drawRect(20, 800, 400, 1000, mPaint);

RectF rect1 = new RectF(20, 1200, 800, 1400);

canvas.drawRoundRect(rect1, 10, 10, mPaint);

}

六 绘制圆

drawCircle 绘制圆

//绘制圆形

private void drawCircle(Canvas canvas) {

int width = canvas.getWidth();

int height = canvas.getHeight();

int halfWidth = width / 2;

int d = height / 3;

int r = d / 2 - 10;

//设置画笔颜色

mPaint.setColor(Color.RED);

//设置画笔宽度

mPaint.setStrokeWidth(2);

//设置画笔样式

mPaint.setStyle(Paint.Style.FILL);

//绘制圆

canvas.drawCircle(halfWidth, (float) (d * 0.5), r, mPaint);

//绘制两个圆实现圆环效果

mPaint.setColor(Color.GREEN);

canvas.drawCircle(halfWidth, (float) (d * 1.5), r, mPaint);

mPaint.setColor(Color.WHITE);

canvas.drawCircle(halfWidth, (float) (d * 1.5), r - 40, mPaint);

//绘制一个圆实现圆环效果

mPaint.setStrokeWidth(40);

mPaint.setColor(Color.BLUE);

mPaint.setStyle(Paint.Style.STROKE);

//半径减去画笔画笔宽度的一半 圆的大小和前面一致

canvas.drawCircle(halfWidth, (float) (d * 2.5), r - 20, mPaint);

}

七 绘制椭圆

drawOval 绘制椭圆

跟绘制圆差不多,唯一不同就是绘制圆是指定圆心和半径,绘制椭圆是指定左上右下4个距离。

//绘制椭圆

private void drawOval(Canvas canvas) {

//设置画笔颜色

mPaint.setColor(Color.RED);

//设置画笔宽度

mPaint.setStrokeWidth(2);

//设置画笔样式

mPaint.setStyle(Paint.Style.FILL);

RectF overRect = new RectF(20, 20, 400, 200);

canvas.drawOval(overRect, mPaint);

mPaint.setColor(Color.GREEN);

mPaint.setStrokeWidth(20);

mPaint.setStyle(Paint.Style.STROKE);

overRect = new RectF(20, 220, 200, 600);

canvas.drawOval(overRect, mPaint);

}

八 绘制圆弧

drawArc 绘制弧

绘制圆弧,可以绘制弧面和弧线。弧面即用弧围成的填充面,弧线即为弧面的轮廓线。

//绘制弧

private void drawAcr(Canvas canvas) {

int width = canvas.getWidth();

//设置画笔颜色

mPaint.setColor(Color.RED);

//设置画笔宽度

mPaint.setStrokeWidth(2);

//设置画笔样式

mPaint.setStyle(Paint.Style.FILL);

//和前面绘制椭圆的矩形一致(正方形也可)

RectF arcRect = new RectF(20, 20, 400, 200);

//根据矩形绘制弧形 开始角度0 扫过角度360 通过中心点首尾连接:true

// 和前面绘制的椭圆效果一致

canvas.drawArc(arcRect, 0, 360, true, mPaint);

canvas.translate(0, width / 5);

canvas.drawArc(arcRect, 0, 90, true, mPaint);

canvas.translate(0, width / 5);

canvas.drawArc(arcRect, 0, 90, false, mPaint);

//正方形

arcRect = new RectF(20, 20, 220, 220);

mPaint.setStrokeWidth(4);

mPaint.setStyle(Paint.Style.STROKE);

canvas.translate(0, width / 5);

//根据矩形绘制弧形 角度从0-1800 首尾连接

canvas.drawArc(arcRect, 0, 180, true, mPaint);

canvas.translate(0, width / 5);

//根据矩形绘制弧形 角度从0-1800 首尾不连接

canvas.drawArc(arcRect, 0, 180, false, mPaint);

mPaint.setStrokeWidth(10);

canvas.translate(width / 2, width / 5);

//drawArc绘制出圆环

canvas.drawArc(arcRect, 0, 270, false, mPaint);

mPaint.setColor(Color.GREEN);

canvas.drawArc(arcRect, 270, 90, false, mPaint);

}

九 绘制文字

drawText 绘制文本

drawPosText 根据位置绘制文本

drawTextOnPath 根据路径绘制文本

//绘制文字

private void drawText(Canvas canvas) {

int width = canvas.getWidth();

int height = canvas.getHeight();

int textHeight = 32;

int halfWidth = width / 2;

//设置画笔颜色

mPaint.setColor(Color.GRAY);

//设置画笔宽度

mPaint.setStrokeWidth(2);

canvas.drawLine(halfWidth, 0, halfWidth, height, mPaint);

mPaint.setColor(Color.BLACK);

//设置文本大小

mPaint.setTextSize(textHeight);

//绘制普通文本

canvas.drawText("绘制普通文本", 0, textHeight, mPaint);

mPaint.setColor(Color.RED);

mPaint.setTextAlign(Paint.Align.LEFT);

//存储画布状态 坐标系

canvas.save();

//平移

canvas.translate(halfWidth, textHeight);

//绘制左对齐文本

canvas.drawText("绘制左对齐文本", 0, textHeight, mPaint);

//恢复上次存储状态

canvas.restore();

mPaint.setColor(Color.GREEN);

mPaint.setTextAlign(Paint.Align.CENTER);

//存储画布状态 坐标系

canvas.save();

//平移

canvas.translate(halfWidth, textHeight * 2);

//绘制居中对齐文本(对齐是根据绘图坐标系而言)

canvas.drawText("绘制居中对齐文本", 0, textHeight, mPaint);

//恢复上次存储状态

canvas.restore();

mPaint.setColor(Color.BLUE);

mPaint.setTextAlign(Paint.Align.RIGHT);

//存储画布状态 坐标系

canvas.save();

//平移

canvas.translate(halfWidth, textHeight * 3);

//绘制右对齐文本

canvas.drawText("绘制右对齐文本", 0, textHeight, mPaint);

//恢复上次存储状态

canvas.restore();

mPaint.setColor(Color.BLACK);

//恢复默认对齐方式

mPaint.setTextAlign(Paint.Align.LEFT);

//设置下划线

mPaint.setUnderlineText(true);

//设置加粗

mPaint.setFakeBoldText(true);

//设置删除线

mPaint.setStrikeThruText(true);

//存储画布状态 坐标系

canvas.save();

//平移

canvas.translate(halfWidth, textHeight * 4);

//绘制下划线加粗文本

canvas.drawText("绘制下划线加粗文本", 0, textHeight, mPaint);

//恢复上次存储状态

canvas.restore();

mPaint.reset();

mPaint.setColor(Color.BLACK);

//设置文本大小

mPaint.setTextSize(textHeight);

//存储画布状态 坐标系

canvas.save();

canvas.translate(width / 3, height / 3);

//旋转

canvas.rotate(45);

//绘制倾斜文本

canvas.drawText("绘制倾斜文本", 0, textHeight, mPaint);

//恢复上次存储状态

canvas.restore();

float[] pos = new float[]{40, 40, 80, 80, 120, 120, 160, 160, 200, 200, 240, 240};

//存储画布状态 坐标系

canvas.save();

canvas.translate(width / 3, height / 2);

canvas.drawPosText("绘制位置文本", pos, mPaint);

//恢复上次存储状态

canvas.restore();

Path path = new Path();

path.cubicTo(550, 750, 350, 250, 850, 800);

//画路径

mPaint.setColor(Color.RED);

mPaint.setStyle(Paint.Style.STROKE);

canvas.drawPath(path,mPaint);

canvas.drawTextOnPath("绘制文本OnPath绘制文本OnPath绘制文本OnPath绘制文本OnPath绘制文本OnPath", path, 50, 0, mPaint);

}

十 绘制Path

drawPath 绘制路径

//path拐点集合

List points = new ArrayList<>();

//绘制Path

private void drawPath(Canvas canvas) {

int width = canvas.getWidth();

int height = canvas.getHeight();

int deltaX = width / 4;

int deltaY = (int) (deltaX * 0.75);

//设置画笔颜色

mPaint.setColor(Color.GRAY);

//设置画笔宽度

mPaint.setStrokeWidth(4);

//Fill模式画面

Path path1 = new Path();

RectF arcRect = new RectF(0, 0, deltaX, deltaY);

path1.addArc(arcRect, 0, 360);

path1.addRect(deltaX, 0, deltaX << 1, deltaY, Path.Direction.CW);

canvas.drawPath(path1, mPaint);

//STROKE模式画线

mPaint.setColor(Color.RED);

mPaint.setStyle(Paint.Style.STROKE);

canvas.translate(0, deltaY << 1);

canvas.drawPath(path1, mPaint);

mPaint.setColor(Color.BLUE);

// mPaint.setStyle(Paint.Style.FILL);

canvas.translate(0, deltaY << 1);

Path path2 = new Path();

path2.lineTo(100, 0); //画线

points.add(new Point(100, 0)); //终点 X: 100 Y: 0

RectF overRect = new RectF(100, -50, 300, 50);

path2.arcTo(overRect, 180, -90); //画椭圆 左下部分

points.add(new Point(200, 50)); //终点 X: 250 Y: 50

overRect = new RectF(200, 0, 400, 100);

path2.arcTo(overRect, 180, 90); //画椭圆右上部分

points.add(new Point(300, 0)); //终点 X: 300 Y: 0

path2.lineTo(350, 50); //画线

points.add(new Point(350, 50)); //终点 X: 350 Y: 50

//画二阶贝塞尔曲线 第一个坐标为控制点 最后为终点

path2.quadTo(450, -50, 500, 150);

points.add(new Point(500, 150)); //终点 X: 500 Y: 150

//画三阶阶贝塞尔曲线 前两个坐标为控制点 最后为终点

path2.cubicTo(600, 150, 700, 0, 380, -200);

points.add(new Point(380, -200)); //终点 X: 480 Y: -200

path2.rLineTo(0, 100);

points.add(new Point(380, -200 + 100)); //终点 X: 480 Y: -100

canvas.drawPath(path2, mPaint);

mPaint.setStrokeWidth(10);

mPaint.setColor(Color.RED);

mPaint.setStrokeCap(Paint.Cap.ROUND);

for (Point point : points) {

canvas.drawPoint(point.x, point.y, mPaint);

}

}

十一 绘制Bitmap

drawBitmap 绘制Bitmap

//绘制Bitmap

private void drawBitmap(Canvas canvas) {

BitmapDrawable drawable = (BitmapDrawable) getResources().getDrawable(R.mipmap.ic_launcher);

Bitmap bitmap = drawable.getBitmap();

//如果bitmap不存在,那么就不执行下面的绘制代码

if (bitmap == null) {

return;

}

//直接完全绘制Bitmap

canvas.drawBitmap(bitmap, 0, 0, mPaint);

//绘制Bitmap的一部分,并对其拉伸

//srcRect定义了要绘制Bitmap的哪一部分

Rect srcRect = new Rect();

srcRect.left = 0;

srcRect.right = bitmap.getWidth();

srcRect.top = 0;

srcRect.bottom = (int) (0.33 * bitmap.getHeight());

float radio = (float) (srcRect.bottom - srcRect.top) / bitmap.getWidth();

//dstRecF定义了要将绘制的Bitmap拉伸到哪里

RectF dstRecF = new RectF();

dstRecF.left = 0;

dstRecF.right = canvas.getWidth();

dstRecF.top = bitmap.getHeight();

float dstHeight = (dstRecF.right - dstRecF.left) * radio;

dstRecF.bottom = dstRecF.top + dstHeight;

canvas.drawBitmap(bitmap, srcRect, dstRecF, mPaint);

}

以上就是大部分的绘制操作,当然还有一些没介绍到,还有一些需要在API21(5.0)以上才能使用,这个使用到的时候可以弄个小demo看下效果,接下来介绍下针对画布变换和画布裁剪做一些介绍。

十二 画布变换

translate 平移

scale 缩放

rotate 旋转

skew 错切

在学习绘制操作的时候很多地方都使用到了translate 和rotate 这里就不再对它们进行操作

1.画布scale

//画布缩放

private void canvasScale(Canvas canvas) {

int width = canvas.getWidth();

int height = canvas.getHeight();

int hWidth = width / 2;

int hHeight = height / 2;

mPaint.setColor(Color.GRAY);

mPaint.setStrokeWidth(2);

mPaint.setStyle(Paint.Style.STROKE);

//使用path 画布中心的X Y 轴

Path path = new Path();

path.moveTo(hWidth, 0);

path.lineTo(hWidth, height);

path.moveTo(0, hHeight);

path.lineTo(width, hHeight);

canvas.drawPath(path, mPaint);

//画布平移

canvas.translate(hWidth, hHeight);

mPaint.setColor(Color.RED);

mPaint.setStrokeWidth(5);

RectF rectF = new RectF(0, 0, 200, 100);

canvas.drawRect(rectF, mPaint);

//默认0,0进行缩放

canvas.scale(1.5f, 1.5f);

mPaint.setColor(Color.BLUE);

canvas.drawRect(rectF, mPaint);

//100,0进行缩放

canvas.scale(1.5f, 1.5f, 100, 0);

mPaint.setColor(Color.GREEN);

canvas.drawRect(rectF, mPaint);

/*

当缩放倍数为负数时,会先进行缩放,然后根据不同情况进行图形翻转:

(设缩放倍数为(a,b),旋转中心为(px,py)):

a<0,b>0:以px为轴翻转

a>0,b<0:以py为轴翻转

a<0,b<0:以旋转中心翻转

*/

//100,0进行缩放 以Y轴翻转

canvas.scale(1f, -1f, 100, 0);

mPaint.setColor(Color.BLACK);

canvas.drawRect(rectF, mPaint);

}

2.画布skew

//画布错切

private void canvasSkew(Canvas canvas) {

mPaint.setColor(Color.RED);

mPaint.setStrokeWidth(5);

mPaint.setStyle(Paint.Style.STROKE);

RectF rectF = new RectF(0, 0, 400, 200);

canvas.translate(100,100);

canvas.drawRect(rectF, mPaint);

canvas.save();

canvas.translate(0,300);

//画布X正方向错切45°

canvas.skew(1f, 0);

canvas.drawRect(rectF, mPaint);

canvas.restore();

canvas.save();

canvas.translate(0,600);

//画布Y负方向错切45°

canvas.skew(0, -1f);

canvas.drawRect(rectF, mPaint);

canvas.restore();

mPaint.setColor(Color.GREEN);

canvas.drawLine(0,400,600,400,mPaint);

}

十三 画布裁剪

clipPath

clipRect

clipRegion(过时)

getClipBounds

//画布裁剪

private void canvasClip(Canvas canvas) {

canvas.drawColor(Color.RED);

canvas.save();

//矩形裁剪

canvas.clipRect(0, 0, 400, 200);

canvas.drawColor(Color.BLUE);

canvas.restore();

canvas.save();

canvas.translate(20, 400);

Path path = new Path();

path.addRect(0, 0, 400, 200, Path.Direction.CCW);

canvas.drawPath(path, mPaint);

//路径裁剪

canvas.clipPath(path);

canvas.drawColor(Color.GREEN);

//获得裁剪边界

Rect bounds = canvas.getClipBounds();

mPaint.setColor(Color.BLACK);

mPaint.setStyle(Paint.Style.STROKE);

mPaint.setStrokeWidth(10);

canvas.drawRect(bounds, mPaint);

canvas.restore();

}

这里针对Canvas的API进行了一些说明,希望对大家有所帮助。没有添加完整工程上来,但是每一个方法都是实际跑过的,只需要在onDraw中调用就可以看到效果了。

转载地址:http://lubzl.baihongyu.com/

你可能感兴趣的文章
2018电影票房分析-谁才是票房之王
查看>>
程序员可以干到多少岁?
查看>>
Storm系列(六)storm和kafka集成
查看>>
东南亚的招聘骗局,程序员请注意!
查看>>
Android 获得View宽高的几种方式
查看>>
iOS正则表达式
查看>>
关于javascript的this指向问题
查看>>
Promise的理解和用法
查看>>
java B2B2C Springboot电子商城系统-高可用的服务注册中心
查看>>
Dubbo的总体架构
查看>>
Spring Cloud微服务架构代码结构详细讲解
查看>>
以太经典硬分叉:矿工欢喜、投资者欢庆、社区高兴的“三赢”之举
查看>>
我的友情链接
查看>>
LVS启(禁)用成员
查看>>
innobackupex 备份报错
查看>>
2016 IT 运维工作计划及学习
查看>>
将一个数的二进制位模式从左到右翻转并输出
查看>>
jQuery学习之jQuery Ajax用法详解
查看>>
关于JEPLUS软件介绍——JEPLUS软件快速开发平台
查看>>
动态增加UIView到当前视图中
查看>>