900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 自定义ViewGroup之仿奥运五环的实现

自定义ViewGroup之仿奥运五环的实现

时间:2019-05-12 02:13:18

相关推荐

自定义ViewGroup之仿奥运五环的实现

图片预览

1. 分析和实现原理

1. 自定义一个圆环2. 自定义ViewGroup,然后添加圆环3. onMeasue和onLayout处理4. 绘制文字

2. 绘制圆环

//平移坐标系到中心点canvas.translate(mCenterX,mCenterY);mPaint.setColor(mRingColor);//两种思路 画圆 或者画圆环canvas.drawCircle(0,0,mRingRadius,mPaint);//或者画圆环// float left = -mRingRadius;// float top = -mRingRadius;// float right = mRingRadius;// float bottom = mRingRadius;// mRectF.set(left,top,right,bottom);// canvas.drawArc(mRectF,0,360,false,mPaint);

3. ViewGroup中添加圆环

int margin = dp2px(8);//添加5个圆环for (int i = 0; i < 5; i++) {MarginLayoutParams lp = new MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);lp.setMargins(margin, margin, 0, margin);addView(new RingProgressBar(context, attrs),lp);}

4. onMeasure处理

这个代码都很简单 没什么解释的

@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int widthMode = MeasureSpec.getMode(widthMeasureSpec);int heightMode = MeasureSpec.getMode(heightMeasureSpec);int widthSize = MeasureSpec.getSize(widthMeasureSpec);int heightSize = MeasureSpec.getSize(heightMeasureSpec);//wrap_content计算宽高int width = 0;int height = 0;//计算上面 下面的宽高int tWidth = 0;int bWidth = 0;int tHeight = 0;int bHeight = 0;for (int i = 0; i < getChildCount(); i++) {View child = getChildAt(i);//测量每一个子孩子的宽高measureChild(child,widthMeasureSpec,heightMeasureSpec);MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();int cWidth = child.getMeasuredWidth() + lp.leftMargin;int cHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;if(i < 3){tWidth += cWidth;tHeight = cHeight;}else{bWidth += cWidth;bHeight = tHeight / 2 + cHeight;}}mRingMaxHeight = Math.max(tHeight,bHeight);width = Math.max(tWidth,bWidth);//要加上文字的高度和上下间距height = Math.max(tHeight,bHeight) + mENDescHeight + mCNDescHeight+ textSpacing * 2;//wrap_content 取子View测量的宽高int measureWidth = widthMode == MeasureSpec.AT_MOST ? width : widthSize;int measureHeight = heightMode == MeasureSpec.AT_MOST ? height : heightSize;setMeasuredDimension(measureWidth,measureHeight);}

5. onLayout处理

计算每一个圆环左上右下的值,完成布局,完成放置子View的位置

@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {//上面下面子view距离左边的间距int tLeft = 0;int bLeft = 0;int top = 0;for (int i = 0; i < getChildCount(); i++) {View child = getChildAt(i);//如果子View是GONE,则不处理if(child.getVisibility() == View.GONE){continue;}MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();int cWidth = child.getMeasuredWidth();int cHeight = child.getMeasuredHeight();//上面三个圆环 top都是一样的。//left值等于前一个圆环的宽度加上左边的margin值if(i < 3){if(i == 0){tLeft = lp.leftMargin;}else {tLeft = tLeft + cWidth + lp.leftMargin;}top = lp.topMargin;child.layout(tLeft, top, tLeft + cWidth, top + cHeight);}else {//下面两个圆环top的高度等于topMargin+上面圆环高度的1/2,左边的left第一个圆环等于// 上面圆环的宽度取它的0.55倍+距离左边的间距,第二个圆环等于下面// 第一个圆环的left+圆环宽度+leftMarginif( i == 3){bLeft = (int) (0.55f * cWidth + lp.leftMargin);}else{bLeft = bLeft + cWidth + lp.leftMargin;}top = (int) (lp.topMargin + 0.5 * cHeight);child.layout(bLeft,top,bLeft + cWidth,top + cHeight);}}}

6. 绘制文字

绘制文字的时候文字的top值=上面圆环的高度+文字之间的间距

@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//画文字float cnY = mRingMaxHeight + textSpacing;float enY = cnY + mCNDescHeight+ textSpacing;canvas.drawText(chineseDesc,mCenterX,cnY,mPaint);canvas.drawText(englishDesc,mCenterX, enY,mPaint);}

7. 小结和源码下载

小结:最核心还是onMeasure和onlayout的处理源码下载:最后统一提供代码下载地址

8.联系方式

QQ:1509815887

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。