canvas教程

模仿QQ运动item的界面

字号+ 作者:H5之家 来源:H5之家 2016-09-29 17:03 我要评论( )

首先按照老规矩,无图无真相嘛,先看看先: 效果图.gif 是不是很像呢,那具体是实现是怎样的呢,即使概括的来说就是 1.计算各个变量的值(记得是会随整个View的大小变化而变化)。 2其次利用好canvas.translate()这个方法,计算好大小移动canvas的原点。 3最后

首先按照老规矩,无图无真相嘛,先看看先:


效果图.gif


是不是很像呢,那具体是实现是怎样的呢,即使概括的来说就是
1.计算各个变量的值(记得是会随整个View的大小变化而变化)。
2其次利用好canvas.translate()这个方法,计算好大小移动canvas的原点。
3最后就是调用api提供的各种方法画图就是了。这么说是不是太过于简略了呢,好,现在就来

看看那具体的吧。首先看看xml有什么参数吧

<com.example.jack.besselcurve.BesselCurveView android:id="@+id/besselCurveView" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" android:layout_centerHorizontal="true" app:besselColor="@color/besselColor" app:besselColorText="@color/besselColorText" app:friendAverageStep="6752" app:averageStep="2603" app:champion="Jack" app:allStep="8765" app:time="17:26" app:ranking="15"> </com.example.jack.besselcurve.BesselCurveView>

各参数对应的解释如下:

//时间 private String time; //所有步数 private int allStop; //还有平均步数 private int friendAverageStep; //平均步数 private int averageStep; //排名 private String ranking; //头像 private Bitmap champion_icon; //冠军名字 private String champion;

接着代码段初始化所有参数:

TypedArray mTypedArray=context.getTheme().obtainStyledAttributes(attrs,R.styleable.BesselCurveView,defStyleAttr,0); int numCount=mTypedArray.getIndexCount(); for(int i=0;i<numCount;i++){ int attr=mTypedArray.getIndex(i); switch(attr){ case R.styleable.BesselCurveView_allStep: allStop=mTypedArray.getInt(attr,0); break; case R.styleable.BesselCurveView_averageStep: averageStep=mTypedArray.getInt(attr,0); break; case R.styleable.BesselCurveView_friendAverageStep: friendAverageStep = mTypedArray.getInt(attr,0); break; case R.styleable.BesselCurveView_time: time=mTypedArray.getString(attr); break; case R.styleable.BesselCurveView_ranking: ranking=mTypedArray.getString(attr); break; case R.styleable.BesselCurveView_champion: champion=mTypedArray.getString(attr); break; case R.styleable.BesselCurveView_besselColor: mBesselCurveColor=mTypedArray.getColor(attr,Color.BLUE); break; case R.styleable.BesselCurveView_besselColorText: besselColorText=mTypedArray.getColor(attr,Color.GRAY); break; } }

这些都是每个自定义都有的相当于模板,来初始化参数,都看的明白吧。接下来也很简单,就是初始化画笔等变量,以便于后面看画图更简单:

public void initValue(){ animSet=new AnimatorSet(); //外圆的画笔 mCirclePaint=new Paint(Paint.ANTI_ALIAS_FLAG); mCirclePaint.setStyle(Paint.Style.STROKE); mCirclePaint.setStrokeWidth(radius/10); mCirclePaint.setStrokeJoin(Paint.Join.ROUND); mCirclePaint.setStrokeCap(Paint.Cap.ROUND); mCirclePaint.setAntiAlias(true); //中间的文字的画笔 mCenterTextPaint=new Paint(); mCenterTextPaint.setColor(mBesselCurveColor); mCenterTextPaint.setTextSize(radius/5); mCenterTextPaint.setAntiAlias(true); //除中间之外的文字的画笔 mTextPaint=new Paint(); mTextPaint.setAntiAlias(true); //最低下的矩形 mBottomRectPaint=new Paint(Paint.ANTI_ALIAS_FLAG); mBottomRectPaint.setColor(mBesselCurveColor); mBottomRectPaint.setAntiAlias(true); //虚线的画笔 mDottedLinePaint = new Paint(); mDottedLinePaint.setAntiAlias(true); mDottedLinePaint.setStyle(Paint.Style.STROKE); mDottedLinePaint.setStrokeWidth(2); mDottedLinePaint.setColor(mBesselCurveColor); mDottedLinePaint.setPathEffect(new DashPathEffect(new float[]{5,5},1)); //画波浪线画笔 WavylinesPaint=new Paint(); WavylinesPaint = new Paint(Paint.ANTI_ALIAS_FLAG); WavylinesPaint.setColor(wavyColor); WavylinesPaint.setStyle(Paint.Style.FILL_AND_STROKE); //虚线的画线 mDottedLinePath=new Path(); //画波浪线画线 WavyLinePath=new Path(); //底下更多的画线 morePath=new Path(); mWaveCount = (int) Math.round(widthView / mWaveLength + 1.5); marginBottomText=radius/4; }

好了,最重要的初始化都差不多了,现在就来画图(画画)吧先贴出所有画的代码然后再逐一讲解吧:

protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.save(); canvas.translate(widthView/2,(heightView*((float)2/3))/2); //画内圆圈 mCirclePaint.setColor(besselColorText); RectF mCircleRectF=new RectF(-radius,-radius,radius,radius); canvas.drawArc(mCircleRectF,120,300,false,mCirclePaint); //画外圆圈 mCirclePaint.setColor(mBesselCurveColor); canvas.drawArc(mCircleRectF,120,mCircleNum,false,mCirclePaint); //画中间的文字 Rect mCenterRect=new Rect(); String tempAllStop=mCenterNum+""; mCenterTextPaint.getTextBounds(tempAllStop,0,tempAllStop.length(),mCenterRect); int halfWidthText=(mCenterRect.right-mCenterRect.left)/2; int halfHeightText=(mCenterRect.bottom-mCenterRect.top)/2; canvas.drawText(tempAllStop,-halfWidthText,halfHeightText,mCenterTextPaint); //画上边的文字 mTextPaint.setColor(besselColorText); mTextPaint.setTextSize(radius/6); String tempFriendAverageStep=stringTemplate(R.string.besselTime,time); Rect mTopRect=new Rect(); mTextPaint.getTextBounds(tempFriendAverageStep,0,tempFriendAverageStep.length(),mTopRect); int halfTopWidthText=(mTopRect.right-mTopRect.left)/2; canvas.drawText(tempFriendAverageStep,-halfTopWidthText,-(halfHeightText+marginText),mTextPaint); //画下边的文字 String tempAverageStep=stringTemplate(R.string.friendAverageStep,friendAverageStep+""); Rect mBottomRect=new Rect(); mTextPaint.getTextBounds(tempAverageStep,0,tempAverageStep.length(),mBottomRect); int halfBottomWidthText=(mBottomRect.right-mBottomRect.left)/2; int mBottomHeightText=(mBottomRect.bottom-mBottomRect.top); canvas.drawText(tempAverageStep,- halfBottomWidthText,mBottomHeightText+halfHeightText+marginText,mTextPaint); //画排名 Rect mNumRect=new Rect(); mCenterTextPaint.getTextBounds(ranking,0,ranking.length(),mNumRect); int halfNum=(mNumRect.right-mNumRect.left)/2; mCenterTextPaint.setTextSize(40); canvas.drawText(ranking,- halfNum,radius,mCenterTextPaint); String rankingLeft=getContext().getResources().getString(R.string.ranking_left); mTextPaint.getTextBounds(rankingLeft,0,rankingLeft.length(),mNumRect); canvas.drawText(rankingLeft,-halfNum-(mNumRect.right- mNumRect.left)/2-20,radius,mTextPaint); canvas.drawText(getContext().getResources().getString(R.string.ranking_right),halfNum+10,radius,mTextPaint); canvas.restore(); //画最近七天和平均运动 mTextPaint.setTextSize(radius/9); canvas.save(); canvas.translate(0,heightView*((float)2/3)); canvas.drawText(getContext().getResources().getString(R.string.nextSevenDay),marginLi neChart,0,mTextPaint); Rect mPercentRect=new Rect(); String mPercentText=stringTemplate(R.string.averageStep,averageStep+""); mTextPaint.getTextBounds(mPercentText,0,mPercentText.length(),mPercentRect); canvas.drawText(mPercentText,widthView-marginLineChart-(mPercentRect.right- mPercentRect.left),0,mTextPaint); //画虚线 mDottedLinePath.moveTo(marginLineChart,marginBottomText); mDottedLinePath.lineTo(widthView-marginLineChart,marginBottomText); canvas.drawPath(mDottedLinePath,mDottedLinePaint); //画7天数据柱状图 mTextPaint.setTextSize(radius/9); int lineWidth=(widthView-marginLineChart*2)/8; mCalendar.setTime(new Date()); RectF mRecf=null; if(mListStep.size()>0){ for(int i=mListStep.size();i>=1;i--){ if(mListStep.get(i-1)!=0){ int startX=marginLineChart+lineWidth*i-radius/23; int endX=marginLineChart+lineWidth*i+radius/23; if(mListStep.get(i-1)>mStandardStop){ //达标 mTextPaint.setColor(mBesselCurveColor); int exceed=mListStep.get(i-1)-mStandardStop; float standard=(float) (mCircleRectHeight*Double.valueOf(exceed/Double.valueOf(mStandardStop))); mRecf=new RectF(startX,marginBottomText-(standard>mCircleRectHeight?mCircleRectHeight:standard) ,endX,marginBottomText+mCircleRectHeight); canvas.drawRoundRect(mRecf,50,50,mTextPaint); }else{ //不达标 mTextPaint.setColor(besselColorText); float noStandard=(float)(mCircleRectHeight*Double.valueOf(mListStep.get(i-1)/Double.valueOf(mStandardStop))); mRecf=new RectF(startX,marginBottomText,endX,marginBottomText+( noStandard>mCircleRectHeight?mCircleRectHeight:noStandard)); canvas.drawRoundRect(mRecf,50,50,mTextPaint); } } //画底下的日期 mTextPaint.setColor(besselColorText); mCalendar.set(Calendar.DAY_OF_MONTH,mCalendar.get(Calendar.DAY_OF_MONTH)-1); Rect rect =new Rect(); String number=stringTemplate(R.string.day,mCalendar.get(Calendar.DAY_OF_MONTH)+""); mTextPaint.getTextBounds(number,0,number.length(),rect); canvas.drawText(number,(marginLineChart+lineWidth*i)-(rect.right-rect.left)/2,marginBottomText+70,mTextPaint); } } canvas.restore(); //画波浪图形 canvas.save(); float mWavyHeight=heightView*((float)4/5)+50; canvas.translate(0,mWavyHeight); WavyLinePath.reset(); WavyLinePath.moveTo(-mWaveLength+ mOffset,0); int wHeight=radius/5; for(int i=0;i<mWaveCount;i++){ WavyLinePath.quadTo((-mWaveLength*3/4)+(i*mWaveLength)+mOffset,wHeight,(-mWaveLength/2)+(i*mWaveLength)+mOffset,0); WavyLinePath.quadTo((-mWaveLength/4)+(i * mWaveLength)+mOffset,- wHeight,i*mWaveLength+mOffset,0); } WavyLinePath.lineTo(widthView,heightView-mWavyHeight); WavyLinePath.lineTo(0,heightView-mWavyHeight); WavyLinePath.close(); canvas.drawPath(WavyLinePath,WavylinesPaint); canvas.restore(); //画最低的信息 float removeHeight=mWavyHeight+(radius/5); canvas.translate(0,removeHeight); float rectHeight=heightView-removeHeight; //画底下的矩形 RectF rect = new RectF(0,0,widthView,rectHeight); canvas.drawRect(rect,mBottomRectPaint); //画头像 int bitmap_icon_x=radius/5; float centerHeight=rectHeight/2; Bitmap bitmap_icon=getRoundCornerImage(champion_icon,50,radius/5,radius/5); canvas.drawBitmap(bitmap_icon,bitmap_icon_x,centerHeight- bitmap_icon.getHeight()/2,null); mTextPaint.setColor(Color.WHITE); mTextPaint.setTextSize(radius/8); //画冠军文字 int champion_x=radius/2; Rect mNameRect=new Rect(); String championMame=stringTemplate(R.string.champion,champion); mTextPaint.getTextBounds(championMame,0,championMame.length(),mNameRect); canvas.drawText(championMame,champion_x,(rectHeight+(mNameRect.bottom-mNameRect.top))/2,mTextPaint); //画查看 String look=getContext().getResources().getString(R.string.check); mTextPaint.getTextBounds(look,0,look.length(),mNameRect); canvas.drawText(look,widthView-(radius*(float)2/3),(rectHeight+(mNameRect.bottom-mNameRect.top))/2,mTextPaint); //画更多图像 float morePoint=(radius*(float)2/3)/2; canvas.drawLine(widthView-morePoint,centerHeight-(mNameRect.bottom- mNameRect.top)/2, widthView-morePoint+15,centerHeight,mTextPaint); canvas.drawLine(widthView-morePoint+15,centerHeight,widthView-morePoint, centerHeight+(mNameRect.bottom-mNameRect.top)/2,mTextPaint); }

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • canvas中的三角运动(2):旋转动画

    canvas中的三角运动(2):旋转动画

    2016-08-21 18:01

  • html5 canvas炫彩运动小球动画特效

    html5 canvas炫彩运动小球动画特效

    2016-06-20 17:00

  • canvas学习之圆周运动,canvas学习圆周

    canvas学习之圆周运动,canvas学习圆周

    2016-06-11 18:00

  • python开发之thread实现布朗运动的方法

    python开发之thread实现布朗运动的方法

    2015-11-13 16:56

网友点评