public class StockPriceLineView extends View {
private int lineColor = Color.parseColor("#29919CAD");
private int CircleFillColor = ContextCompat.getColor(this.getContext(), R.color.C9);
private int yellowColor = Color.parseColor("#FFB019");
private int blueColor = Color.parseColor("#4C8BFF");
private int whiteColor = Color.parseColor("#ffffff");
private int bottomTextSize = DimensionUtil.spToPx(10);
private int toppadding = DimensionUtil.dpToPx(15);
private int strokeHeight = DimensionUtil.dpToPx(2);
private int lineHeight = DimensionUtil.dpToPx(3);
private int roundHeight = DimensionUtil.dpToPx(8);
private int roundStrokeWidth = DimensionUtil.dpToPx(2);
private int textMarginTop = DimensionUtil.dpToPx(8);
private int leftRightMargin = DimensionUtil.dpToPx(0);
private float twoPosition = 0.0f;
private float threePosition = 0.0f;
private List listDta = new ArrayList<>();
private int oneStartX, oneEndX, twoStartX, twoEndX, threeStartX, threeEndX, fourStartX, fourEndX;
private int twoLineStartX, twoLineEndX;
private boolean twoheightIsUse = false;
private Paint paint = new Paint();
public StockPriceLineView(Context context) {
this(context, null);
}
public StockPriceLineView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public StockPriceLineView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint();
}
private void initPaint() {
paint.setStyle(Paint.Style.FILL);
paint.setColor(lineColor);
paint.setTextSize(bottomTextSize);
paint.setAntiAlias(true);
setLayerType(LAYER_TYPE_SOFTWARE, null);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else {
width = getPaddingLeft() + getWidth() + getPaddingRight();
}
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else {
textHeight = measureTextWidth("现价").height();
height = getPaddingTop() + roundHeight + strokeHeight * 2 + textMarginTop * 2 + textHeight * 3 + getPaddingBottom() + 6;
}
setMeasuredDimension(width, height);
}
private int expireTextWidth = 0, textHeight;
private int maxWidth = 0;
private Rect lastTradeTextRect;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int y = strokeHeight + roundHeight / 2 + toppadding;
maxWidth = getWidth();
if (null == (listDta) || listDta.size() == 0) {
return;
}
//1第一个点
int oneXWidth = roundHeight / 2 + roundStrokeWidth + leftRightMargin;
paint.setColor(setColor(0));
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(roundStrokeWidth);
canvas.drawCircle(oneXWidth, y, roundHeight / 2 - 1, paint);
paint.setColor(CircleFillColor);
paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(oneXWidth, y, roundHeight / 2 - roundStrokeWidth / 2 - 1, paint);
paint.setStyle(Paint.Style.FILL);
paint.setStrokeWidth(lineHeight);
paint.setColor(lineColor);
int oneLineXWidth = roundHeight + roundStrokeWidth + leftRightMargin;
int stopX = getWidth() - roundHeight - roundStrokeWidth - leftRightMargin;
canvas.drawLine(oneLineXWidth, y, stopX, y, paint);
int textY = 0;
if (yellowColor == setColor(0)) {
textY = textHeight;
oneStartX = -1;
oneEndX = -1;
} else {
textY = strokeHeight * 2 + roundHeight + textMarginTop + textHeight * 2;
oneStartX = 0;
oneEndX = measureTextWidth(setPriceTxt(3)).width();
}
paint.setColor(setColor(0));
paint.setStyle(Paint.Style.FILL);
canvas.drawText(setPriceTxt(0), 0, textY, paint);
//4最后一个点
int fourXCoordinate = getWidth() - roundHeight / 2 - roundStrokeWidth - leftRightMargin;
paint.setColor(lineColor);
paint.setStrokeWidth(roundStrokeWidth);
paint.setStyle(Paint.Style.FILL);
//paint.setPathEffect(new DashPathEffect(new float[]{5, 5}, 0));//虚线
// canvas.drawLine(lastTradeDot + roundHeight / 2-1, strokeHeight + roundHeight / 2 + toppadding, getWidth() - roundHeight,
// strokeHeight + roundHeight / 2 + toppadding, paint);
paint.setColor(setColor(3));
paint.setStrokeWidth(roundStrokeWidth);
paint.setStyle(Paint.Style.STROKE);
paint.setPathEffect(null);
canvas.drawCircle(fourXCoordinate, y, roundHeight / 2 - 1, paint);
paint.setColor(CircleFillColor);
paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(fourXCoordinate, y, roundHeight / 2 - roundStrokeWidth / 2 - 1, paint);
if (expireTextWidth == 0) {
expireTextWidth = measureTextWidth(setPriceTxt(3)).width();
}
int fourXTxtCoordinate = getWidth() - expireTextWidth - 2 - leftRightMargin;
int lastY = 0;
if (yellowColor == setColor(3)) {
lastY = textHeight;
fourStartX = -1;
fourEndX = -1;
} else {
lastY = strokeHeight * 2 + roundHeight + textMarginTop + textHeight * 2;
fourStartX = fourXTxtCoordinate;
fourEndX = fourXTxtCoordinate + measureTextWidth(setPriceTxt(3)).width();
}
paint.setColor(setColor(3));
paint.setStyle(Paint.Style.FILL);
canvas.drawText(setPriceTxt(3), fourXTxtCoordinate, lastY, paint);
//2
if (lastTradeTextRect == null) {
lastTradeTextRect = measureTextWidth(setPriceTxt(1));
}
int lastTradeDot = (int) (getWidth() * twoPosition) + roundHeight / 2 + roundStrokeWidth;
int twoXCoordinate = lastTradeDot - lastTradeTextRect.width() / 2;
if (twoXCoordinate < 0) {
twoXCoordinate = -twoXCoordinate;
} else if (twoXCoordinate == 0) {
twoXCoordinate = (-twoXCoordinate - lastTradeTextRect.width() / 2) + roundHeight / 2 + roundStrokeWidth;
}
if ((twoXCoordinate + measureTextWidth(setPriceTxt(1)).width()) > maxWidth) {
twoXCoordinate -= twoXCoordinate + measureTextWidth(setPriceTxt(1)).width() + lastTradeTextRect.width() / 2 / 2 - maxWidth;
}
int textOneTopY = 0;
if (yellowColor == setColor(1)) {
textOneTopY = textHeight;
} else {
textOneTopY = strokeHeight * 2 + roundHeight + textMarginTop + textHeight * 2;
if (isUseTwoHeight(twoXCoordinate, twoXCoordinate + (measureTextWidth(setPriceTxt(1)).width()))) {
twoLineStartX = twoXCoordinate;
twoLineEndX = twoXCoordinate + (measureTextWidth(setPriceTxt(1)).width());
textOneTopY += textHeight;
twoheightIsUse = true;
} else {
twoStartX = twoXCoordinate;
twoEndX = twoXCoordinate + (measureTextWidth(setPriceTxt(1)).width());
}
}
paint.setColor(setColor(1));
paint.setStyle(Paint.Style.FILL);
canvas.drawText(setPriceTxt(1), twoXCoordinate, textOneTopY, paint);
paint.setStrokeWidth(strokeHeight);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(lineColor);
// canvas.drawLine(currentDotX + roundHeight / 2-1, strokeHeight + roundHeight / 2 + toppadding, lastTradeDot - roundHeight / 2-1,
// strokeHeight + roundHeight / 2 + toppadding, paint);
paint.setColor(setColor(1));
paint.setStrokeWidth(roundStrokeWidth);
paint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(lastTradeDot, y, roundHeight / 2 - 1, paint);
paint.setColor(CircleFillColor);
paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(lastTradeDot, y, roundHeight / 2 - roundStrokeWidth / 2 - 1, paint);
//3
if (lastTradeTextRect == null) {
lastTradeTextRect = measureTextWidth(setPriceTxt(2));
}
int three = (int) (getWidth() * threePosition) + roundHeight / 2 + roundStrokeWidth;
int threeXCoordinate = three - lastTradeTextRect.width() / 2;
if (threeXCoordinate < 0) {
threeXCoordinate = -threeXCoordinate;
} else if (threeXCoordinate == 0) {
threeXCoordinate = (-threeXCoordinate - lastTradeTextRect.width() / 2) + roundHeight / 2 + roundStrokeWidth;
}
if ((threeXCoordinate + measureTextWidth(setPriceTxt(2)).width()) > maxWidth) {
threeXCoordinate -= threeXCoordinate + measureTextWidth(setPriceTxt(2)).width() + lastTradeTextRect.width() / 2 / 2 - maxWidth;
}
paint.setColor(setColor(2));
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(roundStrokeWidth);
canvas.drawCircle(three, y, roundHeight / 2 - 1, paint);
paint.setColor(CircleFillColor);
paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(three, y, roundHeight / 2 - roundStrokeWidth / 2 - 1, paint);
int threePositionY = 0;
if (yellowColor == setColor(2)) {
threePositionY = textHeight;
} else {
threePositionY = strokeHeight * 2 + roundHeight + textMarginTop + textHeight * 2;
if (isUseTwoHeight(threeXCoordinate, (threeXCoordinate + (measureTextWidth(setPriceTxt(2)).width())))) {
threePositionY += textHeight;
if (isUseThreeHeight(threeXCoordinate, (threeXCoordinate + (measureTextWidth(setPriceTxt(2)).width())))) {
threePositionY += textHeight;
}
}
}
paint.setColor(setColor(2));
paint.setStyle(Paint.Style.FILL);
canvas.drawText(setPriceTxt(2), threeXCoordinate, threePositionY, paint);
// Drawable mDrawable = ContextCompat.getDrawable(getContext(),R.drawable.icon_public_exclamation_line);
// if(bitmap == null||bitmap.isRecycled()){
// bitmap = getBitmap(mDrawable);
// }
//canvas.drawBitmap(bitmap,lastTradeDot+lastTradeTextRect.width()/2+6,textY-textHeight/2-mDrawable.getIntrinsicHeight()/2+5,paint);
}
private boolean isUseTwoHeight(int startX, int endX) {
if (oneEndX != -1 && oneStartX != -1) {
if (startX < oneEndX) {
return true;
}
}
if (fourStartX != -1 && fourEndX != -1) {
if (endX > fourStartX) {
return true;
}
}
return false;
}
private boolean isUseThreeHeight(int startX, int endX) {
if (twoheightIsUse) {
if (startX < twoLineEndX && endX >= twoLineStartX) {
return true;
}
}
return false;
}
private int setColor(int type) {
List data = listDta;
if (3 == data.get(type).type) {
return yellowColor;
}
return blueColor;
}
//0 minVal最低价、1 meanVal均价 2 maxVal最高价 3 nowVal现价
private String setPriceTxt(int type) {
List data = listDta;
switch (data.get(type).type) {
case 0:
return "最低" + String.format("%.2f", data.get(type).price);
case 1:
return "均价" + String.format("%.2f", data.get(type).price);
case 2:
return "最高" + String.format("%.2f", data.get(type).price);
case 3:
return "现价" + String.format("%.2f", data.get(type).price);
}
return "";
}
private Bitmap bitmap;
// @Override
// protected void onDetachedFromWindow() {
// super.onDetachedFromWindow();
// if(bitmap != null&&!bitmap.isRecycled()){
// bitmap.recycle();
// bitmap = null;
// }
// }
private Rect measureTextWidth(String text) {
Paint pFont = new Paint();
Rect rect = new Rect();
pFont.setTextSize(bottomTextSize);
pFont.getTextBounds(text, 0, text.length(), rect);
return rect;//文字宽
}
private final static Bitmap getBitmap(Drawable drawable) {
BitmapDrawable bd = (BitmapDrawable) drawable;
return bd.getBitmap();
}
public void setDates(String minVal, String meanVal, String maxVal, String nowVal) {
listDta.clear();
listDta.add(new StockPriceKeyValueData(0, minVal));
listDta.add(new StockPriceKeyValueData(1, meanVal));
listDta.add(new StockPriceKeyValueData(2, maxVal));
listDta.add(new StockPriceKeyValueData(3, nowVal));
for (int i = 0; i < listDta.size() - 1; i++) {//外层循环控制排序趟数
for (int j = 0; j < listDta.size() - 1 - i; j++) {//内层循环控制每一趟排序多少次
StockPriceKeyValueData data = listDta.get(j);
StockPriceKeyValueData data1 = listDta.get(j + 1);
if (data.price > data1.price) {
listDta.set(j, data1);
listDta.set(j + 1, data);
}
}
}
double longDouble = listDta.get(listDta.size() - 1).price - listDta.get(0).price;
double twoDouble = listDta.get(listDta.size() - 1).price - listDta.get(1).price;
double threeDouble = listDta.get(listDta.size() - 1).price - listDta.get(2).price;
twoPosition = (float) (1 - (twoDouble / longDouble));
threePosition = (float) (1 - (threeDouble / longDouble));
if (MyApplication.SKIN_MODE == MyApplication.SKIN_MODE_NIGHT) {
CircleFillColor = ContextCompat.getColor(this.getContext(), R.color.C9_night);
}
invalidate();
}
}