柱狀圖跟折線圖差不多,依舊只是對位置的計算,效果圖:
代碼:
import java.util.List;
import com.example.mytoolutils.R;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/**
*自定義柱狀圖
*/
public class HistogramView extends View{
private Resources resources;
private Paint paint;
private List<Float>data;
/**Y軸最大值*/
private int YMaxdata;
/**Y軸增長值*/
private int YAdd;
/**繪製區寬度(去除左邊留白)*/
private int width;
/**繪製區高度(去除底部留白)*/
private int height;
/**左邊留白*/
private int margingLeft=20;
/**底部留白*/
private int margingBottom=20;
/**上部留白*/
private int margingTop=60;
/**每根圓柱的寬度*/
private int histogramWidth=20;
/**設置x軸總共值*/
private int Xmaxdata=7;
public HistogramView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initview(context);
}
public HistogramView(Context context, AttributeSet attrs) {
super(context, attrs);
initview(context);
}
public HistogramView(Context context) {
super(context);
initview(context);
}
private void initview(Context context) {
resources=context.getResources();
paint=new Paint();
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
}
/**
* 設置Y軸最大值 ,平均增長值
* @param YMaxdata
* @param YAdd
*/
public void SetYdata(int YMaxdata,int YAdd){
this.YMaxdata=YMaxdata;
this.YAdd=YAdd;
}
/**
* 設置數據
* @param data
*/
public void SetData(List<Float> data){
this.data=data;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
width=w-margingLeft;
height=h-margingBottom-margingTop;
}
@Override
protected void onDraw(Canvas canvas) {
paint.setColor(resources.getColor(R.color.gray_cc));
drawYLine(canvas);
drawXLine(canvas);
drawTopText(canvas);
drawhistogram(canvas);
}
/**
* 繪製頂部文字
* @param canvas
*/
private void drawTopText(Canvas canvas) {
drawText("Kg", canvas,margingLeft/2, margingTop/2);
RectF rectF=new RectF(margingLeft+20, margingTop/2-5, margingLeft+20+50, margingTop/2+5);
canvas.drawRect(rectF, paint);
drawText("高壓", canvas,margingLeft+20+50+20, margingTop/2);
}
/**
* 繪製柱狀圖
* @param canvas
*/
private void drawhistogram(final Canvas canvas) {
RectF rect=null;
for(int i=0;i<Xmaxdata;i++){
rect=new RectF(
margingLeft+(width-30)/Xmaxdata*(i+1)-(histogramWidth/2),
(int)(height-data.get(i)/YMaxdata*height+margingTop),
margingLeft+(width-30)/Xmaxdata*(i+1)+(histogramWidth/2),
margingTop+height-20);
canvas.drawRoundRect(rect,5,5, paint);
}
}
/**
* 橫軸(包含x軸)
* @param canvas
*/
private void drawXLine(Canvas canvas) {
int allXline=YMaxdata/YAdd;
for(int i=0;i<allXline+1;i++){
paint.setColor(resources.getColor(R.color.gray_cc));
canvas.drawLine(margingLeft, margingTop+(height/allXline)*i,width,margingTop+(height/allXline)*i, paint);
drawText(String.valueOf(YAdd*(i)),canvas,margingLeft/2,height-(height/allXline)*i+margingTop);
}
}
/**繪製文字
* @param string
* @param canvas
* @param i
* @param j
*/
private void drawText(String string, Canvas canvas, int x, int y) {
paint.setColor(resources.getColor(R.color.red));
canvas.drawText(string, x, y, paint);
}
/**
* 縱軸(y軸)
* @param canvas
*/
private void drawYLine(Canvas canvas) {
canvas.drawLine(margingLeft,margingTop-10,margingLeft,margingTop+height,paint);
for(int i=0;i<Xmaxdata;i++){
drawText(String.valueOf(i+1), canvas,margingLeft+(width-30)/Xmaxdata*(i+1),height+margingTop+margingBottom/2);
}
}
}
還是文字排版的問題,當然這些細節最後還是要歸咎到計算上面來,計算文字寬高:
Rect rect=new Rect()
paint.getTextBounds("好", 0,1, rect)
Log.i("tag", "height:"+rect.height()+",width:"+rect.width())
//只計算寬度
float width=paint.measureText("好")
應用:
import java.util.ArrayList
import java.util.List
import com.example.mytoolutils.R
import com.example.mytoolutils.R.id
import com.example.mytoolutils.R.layout
import com.example.mytoolutils.view.HistogramView
import android.app.Activity
import android.os.Bundle
public class MyGraphActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_my_graph)
}
@Override
protected void onResume() {
super.onResume()
HistogramView histogramView=(HistogramView) findViewById(R.id.histogramView)
histogramView.SetYdata(100,20)
histogramView.SetData(AddhistogramList())
}
private List<Float> AddhistogramList() {
List<Float> data=new ArrayList<Float>()
data.add(35.45f)
data.add(45.55f)
data.add(65.75f)
data.add(50.95f)
data.add(38.49f)
data.add(70.85f)
data.add(85.45f)
return data
}
}
R.layout.activity_my_graph:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.mytoolutils.activity.MyGraphActivity" >
<com.example.mytoolutils.view.HistogramView
android:id="@+id/histogramView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="10dp"
android:layout_weight="1" >
</com.example.mytoolutils.view.HistogramView>
</LinearLayout>