ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
转载请注明出处:http://blog.csdn.net/wingichoy/article/details/50455412 本系列是为新手准备的自定义view练习项目(大牛请无视),相信在学习过程中,想学自定义view又无从下手,不知道做什么。本系列为新手提供了一系列自定义view的简单实例。看过理解之后,自己实现,相信会有很大提高。 公司需要做地图,无奈美工没有给那种泡泡窗口,于是只能自定义view自己画一个。 由于实现比较简单,便想写下来,给新手做一个自定义view的参考,新人学自定义view的时候也可以先拿这个练手。 首先看效果图,就是一般的泡泡窗啦。 ![](https://box.kancloud.cn/2016-03-21_56efaea26ee3e.jpg) 那么现在就开始了,分析一下,其实就是一个圆角矩形 加上一个三角。画出来就是了。 首先先创建一个类,继承自View  ,重写他的构造方法,这里为了简便就不加自定义属性了。 ~~~ public PopupView(Context context) { this(context,null); } public PopupView(Context context, AttributeSet attrs) { this(context, attrs,0); } public PopupView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } ~~~ 然后是测量他的大小,为了方便,这里只给出EXACTLY的测量值,AT_MOST的时候大家可以自己给一个初始值,这里就不加了 里面有个mRect,其实就是圆角矩形啦。圆角矩形要比整体的view小一点,这里我直接乘上一个百分比来体现,我给的值是mRectPercent = 0.8;(这个处理方式是十分不好的,是一种错误的方式,这里我不想更正了,因为只有错误才能提高。你可以查看下一篇博客,计算了padding,让矩形处于最中间)。 ~~~ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthSize = MeasureSpec.getSize(widthMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); if(widthMode== MeasureSpec.EXACTLY){ mWidth = widthSize; //获取到当前view的宽度 mRectWidth = (int) (mWidth * mRectPercent);//计算矩形的大小 这里是直接给的初值为0.8 也就是说矩形是view大小的0.8倍 下同 } if(heightMode == MeasureSpec.EXACTLY){ mHeight = heightSize;//获取当前view的高度 mRectHeight = (int) (mHeight * mRectPercent+0.1); } setMeasuredDimension(mWidth,mHeight); } ~~~ 测量完成以后接下来就是绘制了,绘制起来也比较简单,关键是计算出关键点的坐标。这里来一张图表示一下 ![](https://box.kancloud.cn/2016-03-21_56efaea27f141.jpg) 只需要把三角的三个点的坐标计算出来就可以了。至于后面加减的数字,其实就是三角形的高和底边长 也很简单,聪明的你一定一看就懂。 那么就把这些坐标画成图形。 ~~~ @Override protected void onDraw(Canvas canvas) { Paint p = new Paint(); p.setColor(Color.parseColor("#2C97DE")); p.setStyle(Paint.Style.FILL); canvas.drawRoundRect(new RectF(0,0,mRectWidth,mRectHeight),10,10,p); Path path = new Path(); path.moveTo(mRectWidth/2-30,mRectHeight); path.lineTo(mRectWidth/2,mRectHeight+20); path.lineTo(mRectWidth/2+30,mRectHeight); path.close(); canvas.drawPath(path,p); super.onDraw(canvas); } ~~~ 其中圆角矩形是用drawRoundRect方法来绘制的,里面是一个基本的矩形,和圆角的半径 三角形是用path来绘制,首先用moveTo设定起点坐标,最后将两条线连接起来,别忘了close成一个封闭的图形。 这样就大功告成泡泡窗,不用麻烦美工啦! 如果你觉得这个自定义view比较简单可以闭着眼睛写出来,你还可以参考进阶一点点的 [自定义圆形百分比,进度条](http://blog.csdn.net/wingichoy/article/details/50334595) 进行练习,总之自定义view并不难,只要多练,就一定会掌握熟练。