美文网首页Android自定义控件
Android自定义View之总结一

Android自定义View之总结一

作者: sgffsg | 来源:发表于2016-06-27 17:47 被阅读466次

    前言

    曾经看过大牛任玉刚的一篇博客--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之总结二

    相关文章

      网友评论

        本文标题:Android自定义View之总结一

        本文链接:https://www.haomeiwen.com/subject/niyzdttx.html