首页 > 代码库 > android自定义折线图
android自定义折线图
BrokenLine控件:
import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.GregorianCalendar; import java.util.List; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.DashPathEffect; import android.graphics.LinearGradient; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PathEffect; import android.graphics.Shader; import android.util.Log; import android.view.View; import android.view.ViewGroup.LayoutParams; import com.qianhua.healthy_brain.R; /** * 线框图 * * @author Administrator * */ public class BrokenLine extends View { private List<Integer> milliliter; private float tb; private float interval_left_right; private float interval_left; private float margin_bottom; private Paint paint_date, paint_brokenLine, paint_dottedline, paint_brokenline_big, framPanint; private int time_index; private Bitmap bitmap_point; private Path path; private float dotted_text; public float getDotted_text() { return dotted_text; } public void setDotted_text(float dotted_text) { this.dotted_text = dotted_text; } private int fineLineColor = 0x5faaaaaa; // 灰色 private int blueLineColor = 0xff00ffff; // 蓝色 private int orangeLineColor = 0xffd56f2b; // 橙色 public BrokenLine(Context context, List<Integer> milliliter) { super(context); init(milliliter); } public void init(List<Integer> milliliter) { if (null == milliliter || milliliter.size() == 0) return; this.milliliter = delZero(milliliter); Resources res = getResources(); tb = res.getDimension(R.dimen.historyscore_tb); interval_left_right = tb * 5.0f; interval_left = tb * 0.5f; margin_bottom=8*tb * 0.2f; paint_date = new Paint(); paint_date.setStrokeWidth(tb * 0.1f); paint_date.setTextSize(tb * 1.2f); paint_date.setColor(fineLineColor); paint_brokenLine = new Paint(); paint_brokenLine.setStrokeWidth(tb * 0.1f); paint_brokenLine.setColor(blueLineColor); paint_brokenLine.setAntiAlias(true); paint_dottedline = new Paint(); paint_dottedline.setStyle(Paint.Style.STROKE); paint_dottedline.setColor(fineLineColor); paint_brokenline_big = new Paint(); paint_brokenline_big.setStrokeWidth(tb * 0.2f); paint_brokenline_big.setColor(fineLineColor); paint_brokenline_big.setAntiAlias(true); framPanint = new Paint(); framPanint.setAntiAlias(true); framPanint.setStrokeWidth(2f); path = new Path(); bitmap_point = BitmapFactory.decodeResource(getResources(), R.drawable.icon_point_blue); setLayoutParams(new LayoutParams( (int) (this.milliliter.size() * interval_left_right), LayoutParams.MATCH_PARENT)); } /** * 移除左右为零的数据 * * @return */ public List<Integer> delZero(List<Integer> milliliter) { List<Integer> list = new ArrayList<Integer>(); int sta = 0; int end = 0; for (int i = 0; i < milliliter.size(); i++) { if (milliliter.get(i) != 0) { sta = i; break; } } for (int i = milliliter.size() - 1; i >= 0; i--) { if (milliliter.get(i) != 0) { end = i; break; } } for (int i = 0; i < milliliter.size(); i++) { if (i >= sta && i <= end) { list.add(milliliter.get(i)); } } time_index = sta; // dotted_text = ((Collections.max(milliliter) - Collections .min(milliliter)) / 12.0f * 5.0f); return list; } protected void onDraw(Canvas c) { if (null == milliliter || milliliter.size() == 0) return; drawStraightLine(c); drawBrokenLine(c); drawDate(c); } /** * 绘制竖线 * * @param c */ public void drawStraightLine(Canvas c) { int count_line = 0; for (int i = 0; i < milliliter.size(); i++) { if (i==0) {//绘制Y轴 c.drawLine(interval_left_right * i, 0, interval_left_right * i, getHeight() - margin_bottom, paint_date); for (int j = 0; j <10; j++) { c.drawText(String.valueOf(10*(j+1)), 0 ,(getHeight()-margin_bottom)/10*(10-(j+1)), paint_date); if (j==5){//绘制虚线 paint_dottedline.setColor(orangeLineColor); Path path = new Path(); path.moveTo(0, (getHeight()-margin_bottom)/10*(10-(j+1))); path.lineTo(getWidth(), (getHeight()-margin_bottom)/10*(10-(j+1))); PathEffect effects = new DashPathEffect(new float[] { tb * 0.3f, tb * 0.3f, tb * 0.3f, tb * 0.3f }, tb * 0.1f); paint_dottedline.setPathEffect(effects); c.drawPath(path, paint_dottedline); } } continue; } //绘制竖线 连续四条为一组 paint_dottedline.setColor(fineLineColor); if (count_line == 0) { c.drawLine(interval_left_right * i, 0, interval_left_right * i, getHeight() - margin_bottom, paint_date); } if (count_line == 2) { c.drawLine(interval_left_right * i, tb * 1.5f, interval_left_right * i, getHeight() - margin_bottom, paint_date); } if (count_line == 1 || count_line == 3) { Path path = new Path(); path.moveTo(interval_left_right * i, tb * 1.5f); path.lineTo(interval_left_right * i, getHeight() - margin_bottom); PathEffect effects = new DashPathEffect(new float[] { tb * 0.3f, tb * 0.3f, tb * 0.3f, tb * 0.3f }, tb * 0.1f); paint_dottedline.setPathEffect(effects); c.drawPath(path, paint_dottedline); } count_line++; if (count_line >= 4) { count_line = 0; } } //绘制X轴 c.drawLine(0, getHeight() - margin_bottom, getWidth(), getHeight() - margin_bottom, paint_brokenline_big); } /** * 绘制折线 * * @param c */ public void drawBrokenLine(Canvas c) { int index = 0; float temp_x = 0; float temp_y = 0; // float base = (getHeight() - tb * 3.0f) / (Collections.max(milliliter) - Collections.min(milliliter)); float base = (getHeight() - margin_bottom) / 100; Shader mShader = new LinearGradient(0, 0, 0, getHeight(), new int[] { Color.argb(100, 0, 255, 255), Color.argb(45, 0, 255, 255), Color.argb(10, 0, 255, 255) }, null, Shader.TileMode.CLAMP); framPanint.setShader(mShader); for (int i = 0; i < milliliter.size() - 1; i++) { Log.e("i", ""+milliliter.get(i)); float x1 = interval_left_right * i; float y1 = getHeight() - margin_bottom - (base * milliliter.get(i)); float Y1 = milliliter.get(i); float x2 = interval_left_right * (i + 1); float y2 = getHeight() - margin_bottom - (base * milliliter.get(i + 1)); float Y2 = milliliter.get(i+1); if ((int) (base * milliliter.get(i + 1)) == 0 && index == 0) { index++; temp_x = x1; temp_y = y1; } if ((int) (base * milliliter.get(i + 1)) != 0 && index != 0) { index = 0; x1 = temp_x; y1 = temp_y; } paint_date.setColor(orangeLineColor); if (i==0) c.drawText(String.valueOf(Y1), x1, y1, paint_date);//绘出第一个值的大小 if (index == 0) { c.drawText(String.valueOf(Y2), x2, y2, paint_date);//绘出第i+1个值的大小 c.drawLine(x1, y1, x2, y2, paint_brokenLine); path.lineTo(x1, y1); if (i != 0) c.drawBitmap(bitmap_point, x1 - bitmap_point.getWidth() / 2, y1 - bitmap_point.getHeight() / 2, null); if (i == milliliter.size() - 2) { path.lineTo(x2, y2); path.lineTo(x2, getHeight()); path.lineTo(0, getHeight()); path.close(); c.drawPath(path, framPanint); c.drawBitmap(bitmap_point, x2 - bitmap_point.getWidth() / 2, y2 - bitmap_point.getHeight() / 2, null); } } } paint_date.setColor(fineLineColor); } /** * 绘制时间 * * @param c */ public void drawDate(Canvas c) { Date date=new Date();//取时间 Calendar calendar =new GregorianCalendar(); calendar.setTime(date); SimpleDateFormat dateFormat=new SimpleDateFormat("MM-dd"); String[] dates=new String[milliliter.size()]; for (int i = 0; i < milliliter.size(); i++) { calendar.add(calendar.DATE,1);//把日期往后增加一天.整数往后推,负数往前移动 date=calendar.getTime(); //这个时间就是日期往后推一天的结果 dates[i]=dateFormat.format(date).toString(); } for (int i = 0; i < milliliter.size(); i += 1) { paint_date.setStrokeWidth(tb * 2.8f); c.drawText(dates[i], interval_left_right * i ,getHeight(), paint_date); } } }
Activity:
import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.widget.RelativeLayout; import com.qianhua.healthy_brain.R; import com.qianhua.healthy_brain.widget.BrokenLine; public class TrainResultActivity extends Activity { RelativeLayout linear; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.train_result); List<Integer> lists = new ArrayList<Integer>();//线性图 范围0-100 for (int i = 0; i < 48; i++) { if (i < 8 || i == 28 || i == 12 || i == 18 || i == 20 || i == 30 || i == 34) { lists.add(0); } else { // int item=getRandom(0, 100); // Log.w(""+i, ""+item); lists.add(getRandom(0, 100)); } } linear= (RelativeLayout) findViewById(R.id.linear); linear.addView(new BrokenLine(this,lists)); } public int getRandom(int min,int max){ return (int) Math.round(Math.random()*(max-min)+min); } }
xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="#f4f4f7" android:orientation="vertical" > <HorizontalScrollView android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_margin="10dp" android:scrollbars="none" > <RelativeLayout android:id="@+id/linear" android:layout_marginTop="30dp" android:layout_width="fill_parent" android:layout_height="fill_parent" > </RelativeLayout> </HorizontalScrollView> </LinearLayout> </LinearLayout>
参考:http://www.apkbus.com/forum.php?mod=viewthread&tid=158365&extra=page%3D1
android自定义折线图
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。