Android自定义View之总结一

前言

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

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

自定义view

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

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

Android自定义View之总结一_第1张图片
字幕view

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

Android自定义View之总结一_第3张图片
自定义加减View

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

Android自定义View之总结一_第4张图片
卡券View

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

Android自定义View之总结一_第5张图片
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);
Android自定义View之总结一_第6张图片
画圆

写文字

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


Android自定义View之总结一_第7张图片
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);
Android自定义View之总结一_第8张图片
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);
    }
Android自定义View之总结一_第9张图片
F7BC07FE-0874-4B18-B9C0-52292F41BDB8.png

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

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

你可能感兴趣的:(Android自定义View之总结一)