仿支付宝股票 猜涨跌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 地址
网友评论