Android 柱狀圖 給柱狀圖添加指示器

QQ視頻20170725110114.gif

繪制柱狀我就不多說了灾前,自行查看如何繪制

我們來看看下面的指示器 是如何繪制的 首先我們來看看跟之前的onDraw 有什么區(qū)別

mIndexMoveMeasure 計算了 指示器于柱狀圖 移動的差距比例 DrawIndex 繪制指示器

Paste_Image.png
DrawIndex 我們來看看里面做了什么
  • 首先這里繪制了 指示器上的三角形 moveX 計算指示器要移動的距離 通過剛才計算的 比例來計算


    Paste_Image.png
  • 繪制指示器文本框 限制右邊距

Paste_Image.png
  • 判斷指示器 當前處于的位置 判斷 topX 也就是三角形的 上邊的x坐標 是不是 矩陣范圍內(nèi)氛雪, 不過這個時候有個問題空白區(qū)域的時候 就找不到因此 做一個處理 找不到時 繪制上一次繪制的文本
Paste_Image.png
完整代碼

<code>

package com.app.framework.widget.chart.rect;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Shader;
import android.support.annotation.Nullable;
import android.text.method.NumberKeyListener;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;

import java.util.ArrayList;
import java.util.List;


public class SlideRectChart extends AbsChart {
    private static final String TAG = "SlideRectChart";

    /**
     * 柱子的畫筆
     */
    private Paint mSlideRectPaint;
    /**繪制時間畫筆*/
    private  Paint mTimePaint;

    /**指示器畫筆*/
    private Paint mIndexPaint;
    /**指示器文本畫筆*/
    private Paint mIndexTxtPaint;
    /**
     * 柱子的大小
     */
    private float mRectSize;

    /**move手指移動與 指針移動的比例*/
    private float mIndexMoveMeasure;

    /**
     * 柱子之間的邊距
     */
    private float mRectLeft;

    /**
     * 右邊超出的范圍
     */
    private float mRectDrawWidth;

    public ArrayList<TimeData> mTimeData;

    /**判斷單位*/
    private SlideRectEnum tag =SlideRectEnum.hour;

    private List<Rect> mRectList;
    private LinearGradient mLinearGradient;

    public  enum  SlideRectEnum{
        day,
        month,
        year,
        hour,

    }
    public SlideRectChart(Context context) {
        super(context);
        init();
    }

    public SlideRectChart(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        if (mSlideRectPaint == null) {
            mSlideRectPaint = new Paint();
        }
        mSlideRectPaint.setAntiAlias(true);
        mSlideRectPaint.setStyle(Paint.Style.FILL);
        mSlideRectPaint.setColor(Color.GREEN);
        if(mTimePaint==null){
            mTimePaint=new Paint();
        }
        mTimePaint.setAntiAlias(true);
        mTimePaint.setStyle(Paint.Style.STROKE);
        mTimePaint.setColor(Color.BLACK);
        mTimePaint.setTextSize(dip2px(12));
        mTimePaint.setTextAlign(Paint.Align.LEFT);


        if(mIndexPaint==null){
            mIndexPaint=new Paint();
        }
        mIndexPaint.setAntiAlias(true);
        mIndexPaint.setStyle(Paint.Style.FILL);
        mIndexPaint.setColor(Color.BLUE);

        if(mIndexTxtPaint==null){
            mIndexTxtPaint=new Paint();
        }
        mIndexTxtPaint.setAntiAlias(true);
        mIndexTxtPaint.setStyle(Paint.Style.FILL);
        mIndexTxtPaint.setColor(Color.WHITE);
        mIndexTxtPaint.setTextSize(dip2px(12));
        mIndexTxtPaint.setTextAlign(Paint.Align.CENTER);


        getBrokenLinePaint().setTextSize(dip2px(12));
        getBrokenLinePaint().setStrokeWidth(dip2px(0.5f));
        getBrokenLinePaint().setStyle(Paint.Style.FILL);
    }

    @Override
    public void setValue(float[] value) {
        super.setValue(value);
        this.mSlideX=0;
    }
    public  void  setTimeData(ArrayList<TimeData> timeData){
        this.mTimeData =timeData;
    }
    public  void  setTag(SlideRectEnum slideRectEnum){
        this.tag=slideRectEnum;
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mRectSize = getViewWidth() / 24;
        mRectLeft = dip2px(4);
        mRectList=new ArrayList<>();
        mLinearGradient = new LinearGradient(getBrokenLineLeft()-1 ,getBrokenLineTop(),getBrokenLineLeft(),getBrokenLineTop(),new int[]{0x00ffffff,Color.BLUE}, null, Shader.TileMode.CLAMP);
        getBrokenLinePaint().setShader(mLinearGradient);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        onTouchEvent(event);
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        /**計算最多移動的距離*/
        mRectDrawWidth = ((mRectLeft * mPoints.length) + (mRectSize * mPoints.length + getBrokenLineLeft() - getViewWidth()));

        mIndexMoveMeasure=getNeedDrawWidth()/mRectDrawWidth;
        DrawRect(canvas);

        DrawIndex(canvas);
    }
    private String oldText="";
    /**繪制指示器*/
    private void DrawIndex(Canvas canvas) {
        float moveX=mSlideX*mIndexMoveMeasure;
        float leftX=getBrokenLineLeft()+moveX;
        float rightX=getBrokenLineLeft()+mRectSize+moveX;
        float topX =rightX-(rightX-leftX)/2;
        float topY=getNeedDrawHeight()+getBrokenLineTop()+2;
        float bottomY=getNeedDrawHeight()+getBrokenLineTop()+mRectSize/2;

        if(leftX>=getViewWidth()-mRectSize-mRectLeft){
            leftX=getViewWidth()-mRectSize-mRectLeft;
            rightX=getViewWidth()-mRectLeft;
            topX=rightX-(rightX-leftX)/2;
        }

        Path mPath=new Path();
        mPath.moveTo(leftX,bottomY);
        mPath.lineTo(topX,topY);
        mPath.lineTo(rightX,bottomY);
        mPath.lineTo(leftX,bottomY);
        canvas.drawPath(mPath,mIndexPaint);

        /**繪制指示器舉證*/
        Rect belowRect=new Rect();
        int  left= (int) (leftX-getBrokenLineLeft());
        int  right = (int) (leftX+getBrokenLineLeft());
        int  top= (int) (topY+getBrokenLineTop()/1.5);
        int  bottom=getViewHeight();
        if(right>=getViewWidth()-mRectLeft){
            left= (int) (getViewWidth()-mRectLeft-getBrokenLineLeft()*2);
            right= (int) (getViewWidth()-mRectLeft);
        }
        belowRect.left=left;
        belowRect.right=right;
        belowRect.top=top;
        belowRect.bottom=bottom;
        canvas.drawRect(belowRect,mIndexPaint);

        int  bx=belowRect.left+(belowRect.right-belowRect.left)/2;


        for (int i = 0; i < mRectList.size(); i++) {
            Rect rect=mRectList.get(i);
            if(rect.left<=topX && rect.right>=topX ){

                if(tag==SlideRectEnum.hour) {
                    oldText=mTimeData.get(i).getHour() + ":00" + " γ: " + floatKeepTwoDecimalPlaces(getValue()[i]);
                    canvas.drawText(oldText, bx, getHeight() - dip2px(2), mIndexTxtPaint);
                }
                if(tag==SlideRectEnum.day) {
                    oldText=mTimeData.get(i).getDay() + "日" + " γ: " + floatKeepTwoDecimalPlaces(getValue()[i]);
                    canvas.drawText(oldText, bx, getHeight() - dip2px(2), mIndexTxtPaint);
                }
                break;
            }
            if(mRectList.size()==i+1){
                canvas.drawText(oldText, bx, getHeight() - dip2px(2), mIndexTxtPaint);
            }
        }




    }


    /**繪制矩陣*/
    private void DrawRect(Canvas canvas) {
        mRectList.clear();
        for (int i = 0; i < mPoints.length; i++) {
            Point point = mPoints[i];
            Rect rect = new Rect();
            int left = (int) ((mRectLeft * i) + (mRectSize * i + getBrokenLineLeft()) - mSlideX);
            int right = ((int) ((mRectLeft * i) + (mRectSize * i + mRectSize + getBrokenLineLeft() - mSlideX)));

            if(tag==SlideRectEnum.hour){
                if(mTimeData!=null){
                    TimeData timeData=mTimeData.get(i);
                    if(i==0 || timeData.getHour()==1){
                        canvas.drawLine(left,getNeedDrawHeight()+getBrokenLineTop(),left,0,getBrokenLinePaint());
                        canvas.drawText(timeData.getDay()+"日",left+2,getBrokenLineTop(),getBrokenLinePaint());
                    }
                }
            }
            if(tag==SlideRectEnum.day){
                if(mTimeData!=null){
                    TimeData timeData=mTimeData.get(i);
                    if(i==0 || timeData.getDay()==1){
                        canvas.drawLine(left,getNeedDrawHeight()+getBrokenLineTop(),left,0,getBrokenLinePaint());
                        canvas.drawText(timeData.getMonth()+"月",left+2,getBrokenLineTop(),getBrokenLinePaint());
                    }
                }
            }


            /**限制柱狀繪制范圍*/
            if (left < getBrokenLineLeft()) {
                left = (int) getBrokenLineLeft();
            }
            if (right < getBrokenLineLeft()) {
                right = (int) getBrokenLineLeft();
            }
            rect.left = left;
            rect.right = right;
            rect.bottom = (int) (getNeedDrawHeight() + getBrokenLineTop());
            rect.top = point.y;

            mRectList.add(rect);

            canvas.drawRect(rect, mSlideRectPaint);



        }
    }

    private float mSlideX = 0;
    private float mLastDownX;



    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mLastDownX = event.getX();
                return  true;
            case MotionEvent.ACTION_UP:
                mSlideX += (mLastDownX - event.getX());
                mLastDownX = event.getX();

                if (mSlideX <= 0) {
                    mSlideX = 0;
                }
                if (mSlideX >= mRectDrawWidth) {
                    mSlideX = mRectDrawWidth;
                }
                postInvalidate();
                return true;

            case MotionEvent.ACTION_MOVE:
                mSlideX += (mLastDownX - event.getX());
                mLastDownX = event.getX();
                if (mSlideX <= 0) {
                    mSlideX = 0;
                }
                if (mSlideX >= mRectDrawWidth) {
                    mSlideX = mRectDrawWidth;
                }
                postInvalidate();
                return true;

        }
        return true;

    }
}

</code >

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末冲泥,一起剝皮案震驚了整個濱河市坐桩,隨后出現(xiàn)的幾起案子砌溺,更是在濱河造成了極大的恐慌升薯,老刑警劉巖意述,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件佣谐,死亡現(xiàn)場離奇詭異肚吏,居然都是意外死亡,警方通過查閱死者的電腦和手機狭魂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門罚攀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人雌澄,你說我怎么就攤上這事斋泄。” “怎么了镐牺?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵炫掐,是天一觀的道長。 經(jīng)常有香客問我睬涧,道長募胃,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任畦浓,我火速辦了婚禮痹束,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘讶请。我一直安慰自己祷嘶,他們只是感情好,可當我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布秽梅。 她就那樣靜靜地躺著抹蚀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪企垦。 梳的紋絲不亂的頭發(fā)上环壤,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天,我揣著相機與錄音钞诡,去河邊找鬼郑现。 笑死,一個胖子當著我的面吹牛荧降,可吹牛的內(nèi)容都是我干的接箫。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼朵诫,長吁一口氣:“原來是場噩夢啊……” “哼辛友!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤废累,失蹤者是張志新(化名)和其女友劉穎邓梅,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體邑滨,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡日缨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了掖看。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片匣距。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖哎壳,靈堂內(nèi)的尸體忽然破棺而出毅待,到底是詐尸還是另有隱情,我是刑警寧澤耳峦,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布恩静,位于F島的核電站,受9級特大地震影響蹲坷,放射性物質(zhì)發(fā)生泄漏驶乾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一循签、第九天 我趴在偏房一處隱蔽的房頂上張望级乐。 院中可真熱鬧,春花似錦县匠、人聲如沸风科。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽贼穆。三九已至,卻和暖如春兰粉,著一層夾襖步出監(jiān)牢的瞬間故痊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工玖姑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留愕秫,地道東北人。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓焰络,卻偏偏與公主長得像戴甩,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子闪彼,可洞房花燭夜當晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫甜孤、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,121評論 4 61
  • 遇見你,沒有太多的開始 可能就只是一句話缴川,一句簡單的問候 什么時候擁抱囱稽,什么時候牽手 什么時候看到你如癡如醉的笑 ...
    虓硯閱讀 203評論 0 2
  • 本來,我想以輕松詼諧的語言來寫這篇文章二跋,可自己的大學生涯是個反面教材,自己的文字又偏深沉流昏,自己對文字的駕馭又欠缺火...
    北嶺老松閱讀 491評論 6 7
  • 創(chuàng)建mysql超級用戶 groupadd mysql useradd -r -g mysql mysql 解壓后更...
    蔚文達閱讀 312評論 0 0