和折线图实现的效果差不多,先贴代码
package com.wisdudu.community.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import java.util.List;
/**
* Created by pc on 2016/3/8.
*/
public class DiagramView extends View {
private Context myContext;
public int paddingLeft;
public int paddingRight;
public int paddingBottom;
public int paddintTop;
int width; //控件宽度
int height; //控件高度
List<Double> listDate1; //数据源
double maxDate; //集合最大值,占满整个高度
int jgwidth; //2点间隔宽度
public int index; //当前选中的index;
List<String> listString1;
List<String> listString2;
int[] x;
int[] y;
static boolean isFist=true;//第一次进来,用于判断点显示不显示要用的
boolean isInit=false; //是否已经传过来初始化所有参数,没有的话,view不显示,ondraw里面判断
public DiagramView(Context context) {
super(context);
this.myContext=context;
}
public DiagramView(Context context, AttributeSet attrs) {
super(context, attrs);
this.myContext=context;
}
public DiagramView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.myContext=context;
}
public void setInit(List<Double> listDate1,List<String> listString1, List<String> listString2){
this.listDate1=listDate1;
this.listString1=listString1;
this.listString2=listString2;
isInit=true;
initDatas();
invalidate();
}
public static enum Type{
week,month
}
/**
* 初始化数据
*/
public void initDatas(){
maxDate=getMaxint(); //算出最大的数
paddingLeft=0;
paddingRight=0;
paddingBottom=30;
paddintTop=120;
x=new int[listDate1.size()];
y=new int[listDate1.size()];
jgwidth=(getWidth()-paddingLeft-paddingRight)/(listDate1.size()-1);
//算出来个坐标点
for(int i=0;i<listDate1.size();i++){
double kuan=getMyWeight(i);
double gao=getMyHeight(listDate1.get(i));
x[i]=(int)kuan;
y[i]=(int)gao;
}
for(int i=0;i<listDate1.size();i++){
if(maxDate==listDate1.get(i)){
index=i;
}
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(!isInit){
return;
}
if (isFist){
initDatas();
isFist=false;
}
canvas.drawColor(Color.parseColor("#49acd5"));
//绘制任意多边形
Paint paint = new Paint();
//设置画笔颜色
paint.setColor(Color.parseColor("#10a679"));
//设置圆弧的宽度
paint.setStrokeWidth(10);
//设置圆弧为空心
paint.setStyle(Paint.Style.STROKE);
//消除锯齿
paint.setAntiAlias(true);
Path path = new Path();
path.moveTo(((int)x[0]), (int)y[0]);
for(int i=0;i<listDate1.size()-1;i++){
int wt = (x[i] + x[i+1]) / 2;
Point p3 = new Point();
Point p4 = new Point();
p3.y = y[i];
p3.x = wt;
p4.y = y[i+1];
p4.x = wt;
path.cubicTo(p3.x, p3.y, p4.x, p4.y, x[i+1],y[i+1]);
}
path.lineTo(getWidth()-paddingLeft,getHeight());
path.lineTo(paddingLeft,getHeight());
path.lineTo(((int)x[0]), (int)y[0]);
paint.setStyle(Paint.Style.FILL);
Shader mShader=new LinearGradient(0,paddintTop,0,getHeight(),
new int[]{ Color.parseColor("#85c8e4"),Color.parseColor("#49acd5")},
null,Shader.TileMode.MIRROR);
// 参数一为渐变起初点坐标x位置,参数二为y轴位置,参数三和四分辨对应渐变终点,最后参数为平铺方式
paint.setShader(mShader);
canvas.drawPath(path, paint);
/**
* 画圆外部蓝色
*/
paint = new Paint();
//设置画笔颜色
paint.setColor(Color.parseColor("#3FFFFFFF"));
//设置圆弧的宽度
paint.setStrokeWidth(1);
//设置圆弧为空心
paint.setStyle(Paint.Style.FILL);
//消除锯齿
paint.setAntiAlias(true);
for(int item=0;item<listDate1.size();item++){
if(index==item){
if(item==0){
//定义一个矩形
RectF rf2 = new RectF(x[item]-15+15, y[item]-15, x[item]+15+15, y[item]+15);
//画圆
canvas.drawOval(rf2, paint);
}else if(item==listDate1.size()-1){
//定义一个矩形
RectF rf2 = new RectF(x[item]-15-15, y[item]-15, x[item]+15-15, y[item]+15);
//画圆
canvas.drawOval(rf2, paint);
}else{
//定义一个矩形
RectF rf2 = new RectF(x[item]-15, y[item]-15, x[item]+15, y[item]+15);
//画圆
canvas.drawOval(rf2, paint);
}
}
}
/**
* 画圆内部白色
*/
paint = new Paint();
//设置画笔颜色
paint.setColor(Color.parseColor("#72FFFFFF"));
//设置圆弧的宽度
paint.setStrokeWidth(1);
//设置圆弧为空心
paint.setStyle(Paint.Style.FILL);
//消除锯齿
paint.setAntiAlias(true);
for(int item=0;item<listDate1.size();item++){
if(index==item){
if(item==0){
//定义一个矩形
RectF rf2 = new RectF(x[item]-10+15, y[item]-10, x[item]+10+15, y[item]+10);
//画圆
canvas.drawOval(rf2, paint);
}else if(item==listDate1.size()-1){
//定义一个矩形
RectF rf2 = new RectF(x[item]-10-15, y[item]-10, x[item]+10-15, y[item]+10);
//画圆
canvas.drawOval(rf2, paint);
}else{
//定义一个矩形
RectF rf2 = new RectF(x[item]-10, y[item]-10, x[item]+10, y[item]+10);
//画圆
canvas.drawOval(rf2, paint);
}
}
}
//画7个直线
/**
*/
paint = new Paint();
paint.setColor(Color.parseColor("#FFFFFF"));
paint.setStrokeWidth(1);
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
for(int item=0;item<listDate1.size();item++){
if(index==item){
//定义一个矩形
if(item==0){
canvas.drawLine(x[item]+15,y[item]+15,x[item]+15,getHeight(),paint);
}else if(item==listDate1.size()-1){
//定义一个矩形
canvas.drawLine(x[item]-15,y[item]+15,x[item]-15,getHeight(),paint);
}else{
canvas.drawLine(x[item],y[item]+15,x[item],getHeight(),paint);
}
}
}
//绘制文字
paint = new Paint();
paint.setFakeBoldText(false); //true为粗体,false为非粗体
//mp.setTextSkewX(-0.5f); //float类型参数,负数表示右斜,整数左斜
//mp.setUnderlineText(true); //true为下划线,false为非下划线
//mp.setStrikeThruText(true); //true为删除线,false为非删除线
paint.setTextSize(24); //设置字体大小,int型,如12
paint.setShader(null);
paint.setStrokeWidth(10);
paint.setColor(Color.WHITE);
for (int i=0;i<x.length;i++){
if(index==i){
if(i==0){
canvas.drawText(listString1.get(i),x[i]-30+30,y[i]-30,paint);
}else if(i==listDate1.size()-1){
Log.e("-->","进来了");
canvas.drawText(listString1.get(i),x[i]-30-50,y[i]-30,paint);
}else{
canvas.drawText(listString1.get(i),x[i]-30,y[i]-30,paint);
}
}
}
for (int i=0;i<x.length;i++){
if(index==i){
if(i==0){
canvas.drawText(listString2.get(i),x[i]-30+30,y[i]-30-25,paint);
}else if(i==listDate1.size()-1){
Log.e("-->","进来了");
canvas.drawText(listString2.get(i),x[i]-30-50,y[i]-30-25,paint);
}else{
canvas.drawText(listString2.get(i),x[i]-30,y[i]-30-25,paint);
}
}
}
}
public double getMaxint(){
double max=0;
for (int i=0;i<listDate1.size();i++){
if(listDate1.get(i)>max){
max=listDate1.get(i);
}
}
return max;
}
//穿入数据源返回数据源应有的高度
public double getMyHeight(double d){
int height=getHeight()-paddintTop;
return (height-(height*(d/maxDate)))+paddintTop;
}
public double getMyWeight(int posotion){
return posotion*jgwidth+paddingLeft;
}
boolean pd1=false;
boolean pd2=false;
float mx1,mx2,my1,my2;
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN: //按下 = 0
mx1=event.getX();
my1=event.getY();
if(pd1){
pd1=false;
}
pd1=true;
Log.e("-->","按下");
break;
case MotionEvent.ACTION_MOVE: //移动 = 2
pd2=true;
Log.e("-->","移动");
break;
case MotionEvent.ACTION_UP: // 抬起 = 1
mx2=event.getX();
my2=event.getY();
float number=mx1-mx2>0?mx1-mx2:mx2-mx1;
if(pd1&pd2&number>10){
if(number>10){
Log.e("-->","滑动");
if((mx1-mx2)>0){
Log.e("-->","往左边滑动");
index=index>0?index-1:index;
}else{
Log.e("-->","往右边滑动");
index=index<listDate1.size()-1?index+1:index;
}
invalidate();
}
}else{
int item=isok(event.getX(),event.getY());
index=item==-1?index:item;
invalidate();
Log.e("-->","抬起");
}
break;
}
//gestureDetector.onTouchEvent(event);
return true;
}
//判断点和矩形是否相交
public boolean isXiangjiao(float dx,float dy,int juBeginX,int juBeginY,int juEndX,int juEndY) {
if(dx>=juBeginX&dy>=juBeginY&dx<=juEndX&dy<=juEndY){
return true;
}else{
return false;
}
}
//判断点击的坐标是否在个圆圈里面,是则返回圈的下标,不是返回-1
public int isok(float djx,float djy){
for(int i=0;i<x.length;i++){
if(isXiangjiao(djx,djy,x[i]-60, y[i]-90, x[i]+60, y[i]+60)){
return i;
}
}
return -1;
}
}
测试activity
package com.example.pc.test.Activity;
import android.app.Activity;
import android.os.Bundle;
import com.example.pc.test.R;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends Activity
{
DiagramView myView;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myView= (DiagramView) findViewById(R.id.myView);
List<Double> listDate1=new ArrayList<>();
listDate1.add(25.0);
listDate1.add(20.0);
listDate1.add(25.0);
listDate1.add(20.0);
listDate1.add(25.0);
listDate1.add(20.0);
listDate1.add(25.0);
List<String> listDate2=new ArrayList<>();
listDate2.add("586分");
listDate2.add("886分");
listDate2.add("386分");
listDate2.add("586分");
listDate2.add("36分");
listDate2.add("856分");
listDate2.add("836分");
List<String> listDate3=new ArrayList<>();
listDate3.add("9.20AM");
listDate3.add("9.20AM");
listDate3.add("19.20AM");
listDate3.add("93.20AM");
listDate3.add("9w.20AM");
listDate3.add("9x.20AM");
listDate3.add("9.20AM");
myView.setInit(listDate1,listDate2,listDate3);
}
}
效果图: