Android自定义View之总结一

前言

曾经看过大牛任玉刚的一篇博客--Android学习路线指南,里面把自定义View定位到中级开发工程师应该掌握的技能之一。我说实话就在两三个月前吧,也已经搞android开发近两年了,但是一直没有真正意义上做过自定义view。其实开发时候就是只要实现功能就行了,所以就做过简单的组合自定义 view。面试的时候面试官要的是那种做过自己绘制,计算显示特殊效果的自定义 view,没做过不好意思只能把你定位到初级菜鸟,回去等通知吧,如果可以我们人事会给你打电话的。

然后我就开始学习自定义 view这一块,学习自定义view就像是学游泳学骑自行车。开始时感觉挺复杂,让人望而生畏。但是你一旦学会就会感觉自定义view没什么,难度也就那样。而且学成后的喜悦是难于言表的,就像是你第一次学会自行车,一个人在小路上自由自在的骑了好远那样。。。

自定义view

一旦学会自定义view,你就感觉自己掌握了游戏里的一个技能,可以随时发大招。下面是我使用自定义view实现的几个效果:

第一个显示字幕view,模仿一步影片里字幕那种向上斜飞而过的效果。这个代码在我的另一篇博客:博客链接

字幕view

第二个是做过一个购物车的加减数量的view,就是我们使用饿了么或者小米商城上买东西时可以点击加号,减号然后数字变动的效果,下图为小米商城的效果
加减view

自定义加减View

第三个是卡券View,这是跟着着别人的开源项目写的

卡券View

第四个是显示订单的执行步骤的view,例如,下单-付款-出货-收货完成

StepView

牛刀小试

其实自定义view就像绘画,绘图,我们可以拿绘图做比较。比如我们需要先准备画笔,颜料,一张白纸。比如你想画一个红色的圆,在现实生活中,也许你需要一个圆规先做一个圆,然后使用画笔蘸一些红色颜料往里面描就行了,就可以描一个红色的圆。但是在Android里面也许更简单。

画圆

Paint circlePaint;//红色圆画笔
Paint bluePaint;//蓝色圆画笔

//初始化
private void init(Context context) {    
    circlePaint=new Paint();    
    bluePaint=new Paint();    
    bluePaint.setColor(Color.BLUE); 
    // 抗锯齿  
    bluePaint.setAntiAlias(true);    
    circlePaint.setColor(Color.RED);
}

在onDraw(Canvas canvas)方法里面,执行画操作,其中(100,100)是圆心坐标,30是半径,circlePaint是画笔

/**
     * Draw the specified circle using the specified paint. If radius is <= 0,
     * then nothing will be drawn. The circle will be filled or framed based
     * on the Style in the paint.
     *
     * @param cx     The x-coordinate of the center of the cirle to be drawn
     * @param cy     The y-coordinate of the center of the cirle to be drawn
     * @param radius The radius of the cirle to be drawn
     * @param paint  The paint used to draw the circle
     */
    public void drawCircle(float cx, float cy, float radius, @NonNull Paint paint) {
        native_drawCircle(mNativeCanvasWrapper, cx, cy, radius, paint.getNativeInstance());
    }

然后我们看一下canvas.drawCircle(float cx, float cy, float radius, @NonNull Paint paint)方法的源码里面的参数都是什么,看上面cx,cy分别为圆心的坐标x,y。radius为圆半径,paint是画圆的画笔

canvas.drawCircle(100,100,30,circlePaint);
canvas.drawCircle(220,100,50,bluePaint);
画圆

写文字

下面先画一个矩形,然后在里面写文字,效果如下:


58F8A5BB-91E8-4539-973D-21687FC20452.png

实现这样的效果,就是先画一个矩形,然后写文字

Paint rectPaint;//矩形画笔
Paint textPaint;//文本画笔


rectPaint=newPaint();
rectPaint.setColor(Color.GRAY);
textPaint=newPaint();
textPaint.setAntiAlias(true);
textPaint.setColor(Color.BLUE);
textPaint.setTextSize(20);

canvas.drawRect(100,100,400,300,rectPaint);
canvas.drawRect(100,100,400,300,rectPaint);

还可以让文字居中显示,居中显示就比较复杂了,需要我们计算文字应该放置的位置,要实现计算我们需要一个Rect,这里也许你知道画笔是Paint,颜色是color,画布是canvas,可是这个Rect是什么鬼,可以先不要管它,只需要知道这里它怎么使用的就行,以后可以深入。学习程序开发就是这样,你要是想对每个类都刨根问底,你会发现你寸步难行,有些东西可以先不去管,等到后就回也许前面的就都豁然开朗,添加的代码如下:

private Rect textBound;//用于计算文本的宽高

//在初始化画笔的时候初始化Rect
textBound=new Rect();

//画图
canvas.drawRect(100,100,400,300,rectPaint);
String str="我是文字!";
textPaint.getTextBounds(str,0,str.length(),textBound);
canvas.drawText(str,250-textBound.width()/2,200+textBound.height()/6,textPaint);
084E204E-5413-40C7-BC24-4869FF0834F9.png

我解释一下是怎么计算的,首先我已经画了一个矩形,然后我就知道矩形的中心点x坐标是(400+100)/2=250,这时文字的宽是通过textBound得到为textBound.width(),所以文字的开始文字x坐标就是250-textBound.width()/2,然后再说y坐标,矩形中心的y坐标是(300+100)/2=200;文字的高是textBound.height(),按道理说,这时文字的中心点坐标应该是200-textBound.height()/2,但是请看下面drawText()的方法源码,这个y让传递的是@param y The y-coordinate of the baseline of the text being drawn,这里的baseline就是相当于汉语拼音本上写四条线的第三条线。所以这个y参数应该传递的是200+textBound.height()/6

/**
     * Draw the text, with origin at (x,y), using the specified paint. The
     * origin is interpreted based on the Align setting in the paint.
     *
     * @param text  The text to be drawn
     * @param x     The x-coordinate of the origin of the text being drawn
     * @param y     The y-coordinate of the baseline of the text being drawn
     * @param paint The paint used for the text (e.g. color, size, style)
     */
    public void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) {
        native_drawText(mNativeCanvasWrapper, text, 0, text.length(), x, y, paint.mBidiFlags,
                paint.getNativeInstance(), paint.mNativeTypeface);
    }
F7BC07FE-0874-4B18-B9C0-52292F41BDB8.png

上面都是一些基础的实例,实际开发中肯定不会这么简单。但是原理都是相通的,只不过也许你要多定义几个画笔,计算上更加复杂,有的甚至计算过于复杂要关心对性能的影响等等

下面我会照着一个的View完整的实现过程写一篇文章--Android自定义View之总结二

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352

推荐阅读更多精彩内容