編輯:關於Android編程
因為在項目中需要用到繪制餅狀圖,所以對github下的android-charts庫進行了精簡和修改,貌似該庫本身有些bug,例如文字繪制有時候會錯位,我改了一些地方,有興趣的可以將下面所有代碼復制進自己項目中,使用方法如下:
mData[0] = new ArrayList(); for(int i=0; i<5; i++) { mData[0].add(new TitleValueColorEntity(mTitle[i], needTime[i], this.getResources().getColor(mColorsId[i]))); } mPieChart.setData(mData[2]);
源碼:
/* * BaseChart.java * Android-Charts * * Created by limc on 2013. * * Copyright 2011 limc.cn All rights reserved. * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.nekocode.xuedao.piechart; import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; import android.view.View; public class BaseChart extends View { /* * (non-Javadoc) * * @param context * * @see android.view.View#BaseChart(Context) */ public BaseChart(Context context) { super(context); } /* * (non-Javadoc) * * @param context * * @param attrs * * @see android.view.View#BaseChart(Context, AttributeSet) */ public BaseChart(Context context, AttributeSet attrs) { super(context, attrs); } /* * (non-Javadoc) * * @param context * * @param attrs * * @param defStyle * * @see android.view.View#BaseChart(Context, AttributeSet, int) */ public BaseChart(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } /* * (non-Javadoc) * * @param widthMeasureSpec * * @param heightMeasureSpec * * @see android.view.View#onMeasure(int, int) */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec)); } /* * (non-Javadoc) * * @param gainFocus * * @param direction * * @param previouslyFocusedRect * * @see android.view.View#onFocusChanged(boolean, int, * android.graphics.Rect) */ @Override protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) { super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); } private int measureWidth(int measureSpec) { int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if (specMode == MeasureSpec.EXACTLY) { result = specSize; } else if (specMode == MeasureSpec.AT_MOST) { result = Math.min(result, specSize); } return result; } private int measureHeight(int measureSpec) { int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if (specMode == MeasureSpec.EXACTLY) { result = specSize; } else if (specMode == MeasureSpec.AT_MOST) { result = Math.min(result, specSize); } return result; } }
/* * PieChart.java * Android-Charts * * Created by limc on 2011/05/29. * * Copyright 2011 limc.cn All rights reserved. * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * */ package com.nekocode.xuedao.piechart; import java.util.List; import com.nekocode.xuedao.utils.MyUtils; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Point; import android.graphics.RectF; import android.graphics.Paint.Style; import android.util.AttributeSet; public class PieChart extends BaseChart { public static final String DEFAULT_TITLE = Pie Chart; public static final boolean DEFAULT_DISPLAY_RADIUS = true; public static final int DEFAULT_RADIUS_LENGTH = 80; public static final int DEFAULT_RADIUS_COLOR = Color.WHITE; public static final int DEFAULT_CIRCLE_BORDER_COLOR = Color.WHITE; public static final Point DEFAULT_POSITION = new Point(0, 0); private Listdata; private String title = DEFAULT_TITLE; private Point position = DEFAULT_POSITION; private int radiusLength = DEFAULT_RADIUS_LENGTH; private int radiusColor = DEFAULT_RADIUS_COLOR; private int circleBorderColor = DEFAULT_CIRCLE_BORDER_COLOR; private boolean displayRadius = DEFAULT_DISPLAY_RADIUS; /* * (non-Javadoc) * * @param context * * @see cn.limc.androidcharts.view.BaseChart#BaseChart(Context) */ public PieChart(Context context) { super(context); } /* * (non-Javadoc) * * @param context * * @param attrs * * @param defStyle * * @see cn.limc.androidcharts.view.BaseChart#BaseChart(Context, * AttributeSet, int) */ public PieChart(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } /* * (non-Javadoc) * * @param context * * @param attrs * * @see cn.limc.androidcharts.view.BaseChart#BaseChart(Context, * AttributeSet) */ public PieChart(Context context, AttributeSet attrs) { super(context, attrs); } /* * (non-Javadoc) * * Called when is going to draw this chart
*銉併儯銉箋儓銈掓浉銇忓墠銆併儭銈姐儍銉夈倰鍛箋伓
*缁樺埗鍥捐〃鏃惰皟鐢/p> * * @param canvas * * @see android.view.View#onDraw(android.graphics.Canvas) */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // get safe rect int rect = super.getWidth() > super.getHeight() ? super.getHeight() : super.getWidth(); // calculate radius length radiusLength = (int) ((rect / 2f) * 0.90); // calculate position position = new Point((int) (getWidth() / 2f), (int) (getHeight() / 2f)); // draw this chart drawCircle(canvas); // draw data on chart drawData(canvas); } protected void drawCircle(Canvas canvas) { Paint mPaintCircleBorder = new Paint(); mPaintCircleBorder.setColor(Color.WHITE); mPaintCircleBorder.setStyle(Style.STROKE); mPaintCircleBorder.setStrokeWidth(2); mPaintCircleBorder.setAntiAlias(true); // draw a circle canvas.drawCircle(position.x, position.y, radiusLength, mPaintCircleBorder); } protected void drawData(Canvas canvas) { if (null != data) { // sum all data's value float sum = 0; for (int i = 0; i < data.size(); i++) { sum = sum + data.get(i).getValue(); } Paint mPaintFill = new Paint(); mPaintFill.setStyle(Style.FILL); mPaintFill.setAntiAlias(true); Paint mPaintBorder = new Paint(); mPaintBorder.setStyle(Style.STROKE); mPaintBorder.setColor(radiusColor); mPaintBorder.setAntiAlias(true); int offset = -90; // draw arcs of every piece for (int j = 0; j < data.size(); j++) { TitleValueColorEntity e = data.get(j); // get color mPaintFill.setColor(e.getColor()); RectF oval = new RectF(position.x - radiusLength, position.y - radiusLength, position.x + radiusLength, position.y + radiusLength); int sweep = Math.round(e.getValue() / sum * 360f); canvas.drawArc(oval, offset, sweep, true, mPaintFill); canvas.drawArc(oval, offset, sweep, true, mPaintBorder); offset = offset + sweep; } float sumvalue = 0f; for (TitleValueColorEntity e : data) { float value = e.getValue(); sumvalue = sumvalue + value; float rate = (sumvalue - value / 2) / sum; mPaintFill.setColor(Color.BLUE); // percentage float percentage = (int) (value / sum * 10000) / 100f; float offsetX = (float) (position.x - radiusLength * 0.5 * Math.sin(rate * -2 * Math.PI)); float offsetY = (float) (position.y - radiusLength * 0.5 * Math.cos(rate * -2 * Math.PI)); Paint mPaintFont = new Paint(); mPaintFont.setColor(Color.WHITE); mPaintFont.setTextSize(MyUtils.sp2px(getContext(), 15)); mPaintFont.setAntiAlias(true); mPaintFont.setStrokeWidth(5); // draw titles String title = e.getTitle(); float realx = 0; float realy = 0; // TODO title position if (offsetX < position.x) { realx = offsetX - mPaintFont.measureText(title) - 5; } else if (offsetX > position.x) { realx = offsetX + 5; } else if (offsetX == position.x) { realx = offsetX - (mPaintFont.measureText(title)/2); } if (offsetY >= position.y) { if (value / sum < 0.2f) { realy = offsetY + 10; } else { realy = offsetY + 5; } } else if (offsetY < position.y) { if (value / sum < 0.2f) { realy = offsetY - 10; } else { realy = offsetY + 5; } } if(percentage != 0.0f) { canvas.drawText(title, realx, realy, mPaintFont); canvas.drawText(String.valueOf((int)value) + min, realx, realy + MyUtils.sp2px(getContext(), 15), mPaintFont); canvas.drawText(String.valueOf(percentage) + %, realx, realy + MyUtils.sp2px(getContext(), 30), mPaintFont); } } } } /** * @return the data */ public List
getData() { return data; } /** * @param data * the data to set */ public void setData(List data) { this.data = data; } /** * @return the title */ public String getTitle() { return title; } /** * @param title * the title to set */ public void setTitle(String title) { this.title = title; } /** * @return the position */ public Point getPosition() { return position; } /** * @param position * the position to set */ public void setPosition(Point position) { this.position = position; } /** * @return the radiusLength */ public int getRadiusLength() { return radiusLength; } /** * @param radiusLength * the radiusLength to set */ public void setRadiusLength(int radiusLength) { this.radiusLength = radiusLength; } /** * @return the radiusColor */ public int getRadiusColor() { return radiusColor; } /** * @param radiusColor * the radiusColor to set */ public void setRadiusColor(int radiusColor) { this.radiusColor = radiusColor; } /** * @return the circleBorderColor */ public int getCircleBorderColor() { return circleBorderColor; } /** * @param circleBorderColor * the circleBorderColor to set */ public void setCircleBorderColor(int circleBorderColor) { this.circleBorderColor = circleBorderColor; } /** * @return the displayRadius */ public boolean isDisplayRadius() { return displayRadius; } /** * @param displayRadius * the displayRadius to set */ public void setDisplayRadius(boolean displayRadius) { this.displayRadius = displayRadius; } }
/* * TitleValueColorEntity.java * Android-Charts * * Created by limc on 2011/05/29. * * Copyright 2011 limc.cn All rights reserved. * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.nekocode.xuedao.piechart; public class TitleValueColorEntity extends TitleValueEntity { private int color; public TitleValueColorEntity(String title, float value, int color) { super(title, value); this.color = color; } public TitleValueColorEntity() { super(); } /** * @return the color */ public int getColor() { return color; } /** * @param color * the color to set */ public void setColor(int color) { this.color = color; } }
/* * TitleValueEntity.java * Android-Charts * * Created by limc on 2011/05/29. * * Copyright 2011 limc.cn All rights reserved. * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.nekocode.xuedao.piechart; public class TitleValueEntity { private String title; private float value; public TitleValueEntity(String title, float value) { super(); this.title = title; this.value = value; } public TitleValueEntity() { super(); } /** * @return the title */ public String getTitle() { return title; } /** * @param title * the title to set */ public void setTitle(String title) { this.title = title; } /** * @return the value */ public float getValue() { return value; } /** * @param value * the value to set */ public void setValue(float value) { this.value = value; } }
1.Toast提醒 為昨天寫的按鈕程序添加一個提醒,在MainActivity中添加如下代碼: Button bt1 = (Button)
前言在前2篇文章中,我們都說到著色器,且在第二篇中正式說到,這著色器只能用在OpenGL ES2.x等可編程管道裡面,而在OpenGL ES1.x是不能用的。但我們一直沒
最近閒來無事,於是研究了一下qq的左滑刪除效果,嘗試著實現了一下,先上效果圖:大致思路原理: - 通過設置margin實現菜單的顯示與隱藏 - 監聽onTouchEven
布局文件復制代碼 代碼如下:<RelativeLayout xmlns:android=http://schemas.android.com/apk/res/and