自定義view(三)之滴滴loading

公司有個福利,就是每天晚上加班之后可以打車,然后每個月報銷一次,感覺生活的幸福感都提升了,有木有,加班之后那么累正好打車,但是我住的比較偏呀,有時候看著滴滴那個轉(zhuǎn)啊轉(zhuǎn)就是沒有車,老煩了,你就不能給我多通知幾個車嗎。正好學(xué)了自定義view那么自己手?jǐn)]一個,嘿嘿。
先上個圖看看效果怎么樣

滴滴的圖

看看是不是特別像滴滴的呢,除了車通知的太多了[捂臉],到了上大餐的時候了,先說一下思路:

  • 大概分成四部分:
    1. 不動的字比如:正在為您叫車,為您優(yōu)先叫車,這個是可以用textView直接寫的
    2. 需要在畫布上寫的,比如:已通知出租車,通知多少輛,“輛”,這些雖然可以用textView寫然后套framelayout,但是這樣需要調(diào)的地方比較多,所以還是自定義
    3. 基礎(chǔ)的灰色的圓,轉(zhuǎn)的橙色的圓
    4. 在圓上邊一直轉(zhuǎn)的那個圓

開始上代碼了
mCirclePaint = new Paint();
mCirclePaint.setStrokeWidth(5);
mCirclePaint.setColor(Color.parseColor("#E3E4E7"));
mCirclePaint.setAntiAlias(true);
mCirclePaint.setStyle(Paint.Style.STROKE);

    mTextPaint = new Paint();
    mTextPaint.setStrokeWidth(1);
    mTextPaint.setColor(Color.parseColor("#8B8C8F"));
    mTextPaint.setAntiAlias(true);
    mTextPaint.setTextSize(20);
    mTextPaint.setStyle(Paint.Style.FILL);


    mTextCountPaint = new Paint();
    mTextCountPaint.setStrokeWidth(1);
    mTextCountPaint.setColor(Color.parseColor("#EC9B70"));
    mTextCountPaint.setAntiAlias(true);
    mTextCountPaint.setTextSize(40);
    mTextCountPaint.setStyle(Paint.Style.FILL);


    mTextUnitPaint = new Paint();
    mTextUnitPaint.setStrokeWidth(1);
    mTextUnitPaint.setColor(Color.parseColor("#EC9B70"));
    mTextUnitPaint.setAntiAlias(true);
    mTextUnitPaint.setTextSize(20);
    mTextUnitPaint.setStyle(Paint.Style.FILL);

    mDrawArcPaint = new Paint();
    mDrawArcPaint.setStrokeWidth(5);
    mDrawArcPaint.setAntiAlias(true);
    mDrawArcPaint.setStyle(Paint.Style.STROKE);

    pos = new float[2];
    tan = new float[2];
    BitmapFactory.Options options = new BitmapFactory.Options();//通過bitmapFactory獲取圖片資源
    mBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.point,options);//獲取資源
    mMatrix = new Matrix();

這次我先設(shè)置了多個畫筆,這樣就不用每次繪制不同的寬度或顏色的圖形就要重新設(shè)置畫筆了,但是這樣就有一個問題,成員變量太多了,會占用比較大的內(nèi)存(這里我要吐槽一下我,我有一個A同事,還有一個B同事,A同事說你為啥方法里用局部變量不用成員變量,B同事說我這個只是在方法中調(diào)用,所以用局部變量,A同事說你這個寫的不對,真是不知道怎么說這個A同事了),如果項目中還是盡量少寫成員變量,而選擇的用局部變量。

現(xiàn)在就是開始畫了圓了

@Override
protected void onDraw(Canvas canvas) {
    canvas.translate(mWidth/2,mHeight/2);//把畫布移到屏幕的中心
    rectF = new RectF(-mWidth/2+50,-mWidth/2+50,mWidth/2-50,mWidth/2-50);

    Path path = new Path();
    path.addCircle(0,0,(mWidth-100)/2, Path.Direction.CW);//cw是順時針
    canvas.drawPath(path,mCirclePaint);//順時針的畫一個圓


    PathMeasure measure = new PathMeasure(path, false);     // 創(chuàng)建 PathMeasure,這是測試path的

    BigDecimal bigDecimal1 = BigDecimal.valueOf(sweepAngle);
    BigDecimal b2 = BigDecimal.valueOf(360);
    float rad = bigDecimal1.divide(b2,MathContext.DECIMAL32).floatValue();//通過bigdecimal來獲取黃線在灰色圓上的位置,在放黃色的小球
    measure.getPosTan(measure.getLength() * rad +10, pos, tan);// 獲取當(dāng)前位置的坐標(biāo)以及趨勢

    mMatrix.reset();                                                        // 重置Matrix
    float degrees = (float) (Math.atan2(tan[1], tan[0]) * 180.0 / Math.PI); // 計算圖片旋轉(zhuǎn)角度

    mMatrix.postRotate(degrees, mBitmap.getWidth() / 2, mBitmap.getHeight() / 2);   // 旋轉(zhuǎn)圖片
    mMatrix.postTranslate(pos[0] - mBitmap.getWidth() / 2, pos[1] - mBitmap.getHeight() / 2);   // 將圖片繪制中心調(diào)整到與當(dāng)前點重合

    Rect rect = new Rect();
    mTextPaint.getTextBounds(notification,0,notification.length(),rect);
    canvas.drawText(notification,-(rect.left+rect.right)/2,rect.bottom,mTextPaint);//寫通知的字

    Rect rectCount = new Rect();
    mTextCountPaint.getTextBounds(String.valueOf(sweepAngle),0,String.valueOf(sweepAngle).length(),rectCount);
    canvas.drawText(String.valueOf(sweepAngle),-(rect.left+rect.right)/2,rect.bottom-rect.top-rect.bottom-rectCount.top/*-rectCount.bottom*/,mTextCountPaint);//寫車的數(shù)量

    canvas.drawText(unit,(rect.left-rect.right)/2+100,rect.bottom-rect.top-rect.bottom-rectCount.top/*-rectCount.bottom*/,mTextUnitPaint);//寫車的單位
//  Log.d(TAG, "onDraw: y=  "+(-rect.top-rectCount.top-rectCount.bottom));
//  Log.d(TAG, "onDraw: rect.top "+rect.top);
//  Log.d(TAG, "onDraw: rectCount.top "+rectCount.top);
//  Log.d(TAG, "onDraw: rectCount.bottom "+rectCount.bottom);

    mMatrix.postRotate(-90);
    canvas.drawBitmap(mBitmap, mMatrix, mDrawArcPaint);
    canvas.drawArc(rectF,-90,sweepAngle,false, mDrawArcPaint);
}

思路也寫到注釋里邊了,哈哈,注意看代碼就可以了,然后這時候還不能動哩,要設(shè)置動怎么辦呢,就是刷新,上次用了pos,這次用Timer+handler。

    final Timer timer = new Timer();
    TimerTask timeTask = new TimerTask() {
        @Override
        public void run() {
            if (i>=360) {
                i = 0;
            }
            Message message = new Message();
            message.what = 1;
            handler.sendMessage(message);
        }
    };
    timer.schedule(timeTask,1000,100);//每100毫秒時候刷新一下,第三個參數(shù)

}

Handler handler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        if (msg.what == 1) {
            diDiView.setData(i+=1);
        }
        super.handleMessage(msg);
    }
};

這就搞定了,然后你就看到通知了好多車就是沒人來接[尷尬]。代碼已經(jīng)上傳到我的git歡迎大家star和fork,也可以關(guān)注我的簡書

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容