仿支付寶股票 猜漲跌View 攜帶百分比View
有兩種需求 ,一種按鈕顯示攜帶字型 看漲 看跌,自帶漲跌動畫。另一種要求實時顯示漲跌比動態。綜合兩種需求自定義一個View。
上面動畫圖 與實際稍微有所不同 本人擅長製作gif 圖....
- 分析兩種需求,兩者可以複用,完全可以定義一個View ,然後利用 Android View 動畫 和 佈局的重新重新整理實現實時繪製。
- 通過方向控制左右View 。
- 繪製字型在View 中間。實現一起漲跌變化
- 測量模式 預設即可
- 原始碼如下:
public class LadderProgressView extends View {
private final String DIRECTION_LEFT = "left";
private String mDirection = DIRECTION_LEFT;
private Path mPath = new Path();
private Paint mPaint;
private String mText = "";
private int mTextColor = Color.parseColor("#ffffff");
private int mBackGroungColor = Color.RED;
private float mTextSize = 40f;
private float mWidth = 0f;
private float mHeight = 0f;
private int mAngle = 45;//預留傾斜角度
public LadderProgressView(Context context) {
this(context, null);
}
public LadderProgressView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public LadderProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ladderView);
mText = ta.getString(R.styleable.ladderView_lad_text);
mDirection = ta.getString(R.styleable.ladderView_lad_direction);
mTextColor = ta.getColor(R.styleable.ladderView_lad_text_color, Color.WHITE);
mTextSize = ta.getDimension(R.styleable.ladderView_lad_text_size, 0f);
mBackGroungColor = ta.getColor(R.styleable.ladderView_lad_background_color, 0);
mAngle = ta.getInt(R.styleable.ladderView_lad_angle, 0);
ta.recycle();
mPaint = new Paint();
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(mBackGroungColor);
mPaint.setAntiAlias(true);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
this.mHeight = h;
this.mWidth = w;
}
@Override
protected void onDraw(Canvas canvas) {
mPath.reset();
if (mDirection.equals(DIRECTION_LEFT)) {
setLadderLeftDraw();
} else {
setLadderRightDraw();
}
mPath.close();
canvas.drawPath(mPath, mPaint);
if (!TextUtils.isEmpty(mText)) {
drawText(canvas);
}
}
public void setLadderLeftDraw() {
//設定將要用來畫扇形的矩形的輪廓
float r = mHeight / 2;//做圓弧半徑
// mPath.addCircle(mHeight / 2, mHeight / 2, mHeight / 2, Path.Direction.CW)
//先畫半圓
RectF roundRectT = new RectF(0f, 0f, mHeight / 2, mHeight);
float[] array = {r, r, 0f, 0f, 0f, 0f, r, r};
mPath.addRoundRect(roundRectT, array, Path.Direction.CCW);
//右邊斜邊
mPath.moveTo(mHeight / 2, 0f);
// 連線路徑到點
mPath.lineTo(mWidth, 0f);
double x = mWidth - mHeight * (Math.tan(Math.toRadians(mAngle)));
mPath.lineTo((float) x, mHeight);
mPath.lineTo(mHeight / 2, mHeight);
}
public void setLadderRightDraw() {
float r = mHeight / 2;
RectF roundRectT = new RectF(mWidth - mHeight / 2, 0f, mWidth, mHeight);
float[] array = {0f, 0f, r, r, r, r, 0f, 0f};
mPath.addRoundRect(roundRectT, array, Path.Direction.CCW);
double x = mHeight * (Math.tan(Math.toRadians(mAngle)));
mPath.moveTo((float) x, 0f);
// 連線路徑到點
mPath.lineTo(mWidth - mHeight / 2, 0f);
mPath.lineTo(mWidth - mHeight / 2, mHeight);
mPath.lineTo(0f, mHeight);
}
public void drawText(Canvas canvas) {
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setAntiAlias(true);
paint.setTextSize(mTextSize);
paint.setColor(mTextColor);
paint.setTextAlign(Paint.Align.CENTER);
Rect targetRect = new Rect(0, 0, (int) mWidth, (int) mHeight);
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
float top = fontMetrics.top;//為基線到字型上邊框的距離,即上圖中的top
float bottom = fontMetrics.bottom;//為基線到字型下邊框的距離,即上圖中的bottom
float baseLineY = (targetRect.centerY() - top / 2 - bottom / 2);
// val fontMetrics = paint.fontMetricsInt
// val baseline = (targetRect.bottom + targetRect.top - fontMetrics.bottom - fontMetrics.top) / 2
// 下面這行是實現水平居中,drawText對應改為傳入targetRect.centerX()
canvas.drawText(mText, targetRect.centerX(), baseLineY, paint);
}
}
複製程式碼
最後 Demo 地址