本文实例为大家分享了Android自定义View画天气预报折线图的具体代码,供大家参考,具体内容如下
效果图如下:
刚开始尝试用第三方画曲线的框架来画效果图,后来发现曲线间的阴影当有负数的度数的时候画不出来,而且不需要点击放大、点点可点的效果,用框架显得很臃肿,所以最后用自定义View来画的折线图。自定义画折线图的大致思路:这个图是有多个四边形组成的(4个点连接起来就是一个四边形),两边延伸:添加四个多余的点,将左右的边距设置成负数即可。
代码如下:
public class WeatherChartView extends View {
private float mXAxis[] ;
private float mYAxisDay[] ;
private float mYAxisNight[] ;
private int LENGTH ;
private int mTempDay[] ;
private int mTempNight[] ;
private int mHeight;
private float mTextSize;
private float mRadius ;
private float mRadiusToday ;
private float mTextSpace ;
private float mStokeWidth ;
private int mColorDay = Color.parseColor("#ffffff");
private int mColorNight = Color.parseColor("#ffffff");;
private int mTextColor = Color.parseColor("#ffffff");;
private float mDensity;
private float mSpace;
@SuppressWarnings("deprecation")
public WeatherChartView(Context context, AttributeSet attrs) {
super(context, attrs);
mDensity = getResources().getDisplayMetrics().density;
mRadius = 3 * mDensity;
mRadiusToday = 3 * mDensity;
//mSpace = 3 * mDensity;
mTextSpace = 10 * mDensity;
mStokeWidth = 2 * mDensity;
mTextSize = BreakRuleTools.dip2px(context, 12);
}
public WeatherChartView(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mHeight == 0) {
// 设置控件高度,x轴集合
setHeightAndXAxis();
}
// 计算y轴集合数值
computeYAxisValues();
// 画白天折线图
drawChart(canvas, mColorDay, mTempDay, mYAxisDay, 0);
// 画夜间折线图
drawChart(canvas, mColorNight, mTempNight, mYAxisNight, 1);
}
private void computeYAxisValues() {
// 存放白天最低温度
int minTempDay = mTempDay[0];
// 存放白天最高温度
int maxTempDay = mTempDay[0];
for (int item : mTempDay) {
if (item < minTempDay) {
minTempDay = item;
}
if (item > maxTempDay) {
maxTempDay = item;
}
}
// 存放夜间最低温度
int minTempNight = mTempNight[0];
// 存放夜间最高温度
int maxTempNight = mTempNight[0];
for (int item : mTempNight) {
if (item < minTempNight) {
minTempNight = item;
}
if (item > maxTempNight) {
maxTempNight = item;
}
}
// 白天,夜间中的最低温度
int minTemp = minTempNight < minTempDay ? minTempNight : minTempDay;
// 白天,夜间中的最高温度
int maxTemp = maxTempDay > maxTempNight ? maxTempDay : maxTempNight;
// 份数(白天,夜间综合温差)
float parts = maxTemp - minTemp;
// y轴一端到控件一端的距离
float length = mSpace + mTextSize + mTextSpace + mRadius;
// y轴高度
float yAxisHeight = mHeight - length * 2;
// 当温度都相同时(被除数不能为0)
if (parts == 0) {
for (int i = 0; i < LENGTH; i++) {
mYAxisDay[i] = yAxisHeight / 2 + length;
mYAxisNight[i] = yAxisHeight / 2 + length;
}
} else {
float partValue = yAxisHeight / parts;
for (int i = 0; i < LENGTH; i++) {
mYAxisDay[i] = mHeight - partValue * (mTempDay[i] - minTemp) - length;
mYAxisNight[i] = mHeight - partValue * (mTempNight[i] - minTemp) - length;
}
}
}
private void drawChart(Canvas canvas, int color, int temp[], float[] yAxis, int type) {
color = Color.parseColor("#ffffff");
// 线画笔
Paint linePaint = new Paint();
// 抗锯齿
linePaint.setAntiAlias(true);
// 线宽
linePaint.setStrokeWidth(mStokeWidth);
linePaint.setColor(color);
// 空心
linePaint.setStyle(Paint.Style.STROKE);
// 点画笔
Paint pointPaint = new Paint();
pointPaint.setAntiAlias(true);
pointPaint.setColor(color);
// 字体画笔
Paint textPaint = new Paint();
textPaint.setAntiAlias(true);
textPaint.setColor(mTextColor);
textPaint.setTextSize(mTextSize);
// 文字居中
textPaint.setTextAlign(Paint.Align.CENTER);
int alpha1 = 102;
int alpha2 = 255;
for (int i = 0; i < LENGTH; i++) {
// 画线
if (i < LENGTH - 1) {
// 昨天
if (i == -1) {
linePaint.setAlpha(alpha1);
// 设置虚线效果
linePaint.setPathEffect(new DashPathEffect(new float[]{2 * mDensity, 2 * mDensity}, 0));
// 路径
Path path = new Path();
// 路径起点
path.moveTo(mXAxis[i], yAxis[i]);
// 路径连接到
path.lineTo(mXAxis[i + 1], yAxis[i + 1]);
canvas.drawPath(path, linePaint);
} else {
if(type == 0) {
linePaint.setAlpha(76);
linePaint.setPathEffect(null);
linePaint.setStyle(Paint.Style.FILL);//设置实心
Path path = new Path(); //Path对象
path.moveTo(mXAxis[i], mYAxisDay[i]); //起始点
path.lineTo(mXAxis[i + 1], mYAxisDay[i + 1]); //连线到下一点
path.lineTo(mXAxis[i + 1], mYAxisNight[i + 1]); //连线到下一点
path.lineTo(mXAxis[i], mYAxisNight[i]); //连线到下一点
path.lineTo(mXAxis[i], mYAxisDay[i]); //连线到下一点
canvas.drawPath(path, linePaint); //绘制任意多边形
}
//canvas.drawLine(mXAxis[i], yAxis[i], mXAxis[i + 1], yAxis[i + 1], linePaint);
}
}
// 画点
if (i != 1) {
// 昨天
if (i == 0 || i == LENGTH - 1) {
} else {
pointPaint.setAlpha(alpha2);
canvas.drawCircle(mXAxis[i], yAxis[i], mRadius, pointPaint);
}
// 今天
} else {
pointPaint.setAlpha(alpha2);
canvas.drawCircle(mXAxis[i], yAxis[i], mRadiusToday, pointPaint);
}
// 画字
// 昨天
if (i == 0 || i == LENGTH - 1) {
} else {
textPaint.setAlpha(alpha2);
drawText(canvas, textPaint, i, temp, yAxis, type);
}
}
}
private void drawText(Canvas canvas, Paint textPaint, int i, int[] temp, float[] yAxis, int type) {
switch (type) {
case 0:
// 显示白天气温
canvas.drawText(temp[i] + "°", mXAxis[i], yAxis[i] - mRadius - mTextSpace, textPaint);
break;
case 1:
// 显示夜间气温
canvas.drawText(temp[i] + "°", mXAxis[i], yAxis[i] + mTextSpace + mTextSize, textPaint);
break;
}
}
private void setHeightAndXAxis() {
mHeight = getHeight();
// 控件宽
int width = getWidth();
int i = LENGTH - 2;
// 每一份宽
float w = width / (i*2);
for(int j =0;j<LENGTH;j++){
if(j == 0){
mXAxis[j] = 0;
} else if(j == LENGTH -1){
mXAxis[j] = width;
} else{
mXAxis[j] = w * (2*j -1);
}
}
}
public void setTempDay(int[] tempDay) {
mTempDay = tempDay;
LENGTH = mTempDay.length;
mXAxis = new float[LENGTH];
mYAxisDay = new float[LENGTH];
mYAxisNight = new float[LENGTH];
}
public void setTempNight(int[] tempNight) {
mTempNight = tempNight;
}
public void setColorDay(){}
}
布局代码:
<com.pingan.carowner.weather.view.WeatherChartView
android:id="@+id/line_char"
android:layout_width="match_parent"
android:layout_height="180dp"
android:layout_below="@id/weather_over_view_item3"
android:layout_centerInParent="true"/>
代码引用:
// 设置白天温度曲线
mChartView = (WeatherChartView) findViewById(R.id.line_char);
mChartView.setTempDay(highTemp);//highTemp 高温度集合
// 设置夜间温度曲线
mChartView.setTempNight(lowTemp);//lowTemp 低温集合
mChartView.invalidate();
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。