仿支付寶股票 猜漲跌View

迷失no發表於2019-03-26

仿支付寶股票 猜漲跌View 攜帶百分比View

漲跌演示

有兩種需求 ,一種按鈕顯示攜帶字型 看漲 看跌,自帶漲跌動畫。另一種要求實時顯示漲跌比動態。綜合兩種需求自定義一個View。

上面動畫圖 與實際稍微有所不同 本人擅長製作gif 圖....

  1. 分析兩種需求,兩者可以複用,完全可以定義一個View ,然後利用 Android View 動畫 和 佈局的重新重新整理實現實時繪製。
  2. 通過方向控制左右View 。
  3. 繪製字型在View 中間。實現一起漲跌變化
  4. 測量模式 預設即可
  5. 原始碼如下:
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 地址

相關文章