package suda.sudamodweather.widget;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
import suda.sudamodweather.dao.greendao.WeekForeCast;
import suda.sudamodweather.util.DateTimeUtil;
import suda.sudamodweather.util.ScreenUtil;
import suda.sudamodweather.util.WeatherIconUtil;
/**
* Created by ghbha on 2016/5/13.
*/
public class WeekForecastView extends View {
public WeekForecastView(Context context) {
super(context);
this.context = context;
}
public WeekForecastView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
}
public WeekForecastView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context = context;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
width = ScreenUtil.getScreenWidth(context);
height = width - getFitSize(20);
leftRight = getFitSize(30);
radius = getFitSize(8);
setMeasuredDimension((int) width, (int) height);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (foreCasts.size() == 0)
return;
paint.setColor(Color.WHITE);
paint.setAntiAlias(true);
paint.setStrokeWidth(0);
paint.setTextAlign(Paint.Align.CENTER);
paint.setTextSize(ScreenUtil.getSp(context, 13));
drawWeatherDetail(canvas);
}
private void drawWeatherDetail(Canvas canvas) {
float weekPaddingBottom = getFitSize(200);
float weekInfoPaddingBottom = getFitSize(40);
float linePaddingBottom = getFitSize(330);
float tempPaddingTop = getFitSize(20);
float tempPaddingBottom = getFitSize(45);
//获取每个天气所占空间
float lineHigh = getFitSize(320);
float widthAvg = (width - leftRight) / foreCasts.size();
float heightAvg = lineHigh / maxMinDelta;
Matrix matrix = new Matrix();
matrix.postScale(0.45f, 0.45f); //长和宽放大缩小的比例
Path pathTempHigh = new Path();
Path pathTempLow = new Path();
float paddingLeft = 0;
int i = 1;
List<PointF> mPointHs = new ArrayList<>();
List<PointF> mPointLs = new ArrayList<>();
for (WeekForeCast foreCast : foreCasts) {
paddingLeft = leftRight / 2 + (i - 1 + 0.5f) * widthAvg;
if (type == TYPE_LINE) {
if (i == 1) {
pathTempHigh.moveTo(paddingLeft, height - (linePaddingBottom + (foreCast.getTempH() - tempL) * heightAvg));
pathTempLow.moveTo(paddingLeft, height - (linePaddingBottom + (foreCast.getTempL() - tempL) * heightAvg));
} else {
pathTempHigh.lineTo(paddingLeft, height - (linePaddingBottom + (foreCast.getTempH() - tempL) * heightAvg));
pathTempLow.lineTo(paddingLeft, height - (linePaddingBottom + (foreCast.getTempL() - tempL) * heightAvg));
}
paint.setStyle(Paint.Style.FILL);
paint.setStrokeWidth(getFitSize(2));
canvas.drawCircle(paddingLeft, height - (linePaddingBottom + (foreCast.getTempH() - tempL) * heightAvg), radius, paint);
canvas.drawCircle(paddingLeft, height - (linePaddingBottom + (foreCast.getTempL() - tempL) * heightAvg), radius, paint);
} else {
PointF pointFH = new PointF(paddingLeft, height - (linePaddingBottom + (foreCast.getTempH() - tempL) * heightAvg));
mPointHs.add(pointFH);
PointF pointFL = new PointF(paddingLeft, height - (linePaddingBottom + (foreCast.getTempL() - tempL) * heightAvg));
mPointLs.add(pointFL);
}
paint.setStrokeWidth(0);
paint.setStyle(Paint.Style.STROKE);
canvas.drawText(foreCast.getTempH() + "°", paddingLeft, height - (linePaddingBottom + tempPaddingTop + (foreCast.getTempH() - tempL) * heightAvg), paint);
canvas.drawText(foreCast.getTempL() + "°", paddingLeft, height - (linePaddingBottom - tempPaddingBottom + (foreCast.getTempL() - tempL) * heightAvg), paint);
//星期
canvas.drawText(DateTimeUtil.getWeekOfDate(foreCast.getWeatherDate()), paddingLeft, height - (weekPaddingBottom), paint);
//天气图标
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), WeatherIconUtil.getWeatherIconID(foreCast.getWeatherConditionStart()));
Bitmap bitmapDisplay = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
canvas.drawBitmap(bitmapDisplay,
paddingLeft - bitmapDisplay.getWidth() / 2, height - getFitSize(8) - ((weekPaddingBottom - weekInfoPaddingBottom) / 2 + weekInfoPaddingBottom) - bitmapDisplay.getHeight() / 2, paint);
bitmap.recycle();
bitmapDisplay.recycle();
//天气描述
canvas.drawText(foreCast.getWeatherConditionStart(), paddingLeft, height - (weekInfoPaddingBottom), paint);
i++;
}
paint.setStrokeWidth(getFitSize(3));
paint.setStyle(Paint.Style.STROKE);
if (type == TYPE_LINE) {
canvas.drawPath(pathTempHigh, paint);
canvas.drawPath(pathTempLow, paint);
} else {
drawBezier(canvas, mPointHs, pathTempHigh);
drawBezier(canvas, mPointLs, pathTempLow);
}
}
private void drawBezier(Canvas canvas, List<PointF> pointFs, Path path) {
path.reset();
for (int i = 0; i < pointFs.size(); i++) {
PointF pointCur = pointFs.get(i);
PointF pointPre = null;
if (i > 0)
pointPre = pointFs.get(i - 1);
if (i == 0) {
path.moveTo(pointCur.x, pointCur.y);
} else {
path.quadTo(pointPre.x, pointPre.y, (pointPre.x + pointCur.x) / 2, (pointPre.y + pointCur.y) / 2);
}
}
path.lineTo(pointFs.get(pointFs.size() - 1).x, pointFs.get(pointFs.size() - 1).y);
canvas.drawPath(path, paint);
}
private int getMaxMinDelta() {
if (foreCasts.size() > 0) {
tempH = foreCasts.get(0).getTempH();
tempL = foreCasts.get(0).getTempL();
for (WeekForeCast weekForeCast : foreCasts) {
if (weekForeCast.getTempH() > tempH) {
tempH = weekForeCast.getTempH();
}
if (weekForeCast.getTempL() < tempL) {
tempL = weekForeCast.getTempL();
}
}
return tempH - tempL;
}
return 0;
}
public void setForeCasts(List<WeekForeCast> foreCasts) {
this.foreCasts.clear();
this.foreCasts.addAll(foreCasts);
maxMinDelta = getMaxMinDelta();
this.invalidate();
}
private float getFitSize(float orgSize) {
return orgSize * width * 1.0f / 1080;
}
private final static String TAG = "ForeCastView";
private float height, width;
private Paint paint = new Paint();
private Context context;
private List<WeekForeCast> foreCasts = new ArrayList<>();
private float maxMinDelta;
private int tempH, tempL;
private float radius = 0;
private float leftRight;
private static final int TYPE_LINE = 0;
private static final int TYPE_BESSEL = 1;
private int type = TYPE_BESSEL;
}