實(shí)現(xiàn)豎直的步驟進(jìn)度條

實(shí)現(xiàn)豎直的步驟進(jìn)度條漩蟆,先看效果:


QQ截圖20160527173654.png

可以看到罚斗,實(shí)現(xiàn)的主要難點(diǎn)在于步驟條的線的高度是要跟右邊的布局保持一致的跺株,而右邊的布局的高度是不定的郑什,也就是用 wrap_content府喳,
所以如果左邊線高度使用 match_parent 的話就會(huì)撐到滿屏。

所有解決方法就是蘑拯,定義一個(gè) ViewGroup 包著左邊的線和右邊的布局劫拢,然后獲取這個(gè) ViewGroup 的高度作為左邊的線的高度。

這里的 ViewGroup 我選擇繼承 LinearLayout 强胰,也可以繼承其他舱沧。
看代碼:

public class ProLinearLayout extends LinearLayout {

    private ProLine mProLine;   //左邊的進(jìn)度條
    //線的類型,實(shí)線還是虛線
    public final static String typeSolid = "solid";  
    public final static String typeDotted = "dotted";
    //是否是第一個(gè)或者是最后一個(gè)線
    private boolean isLastOne = false;
    private boolean isTopOne = false;
    //最上面的一個(gè)的線是不是虛線
    private boolean isTopTypeDotted = false;
     
    private String lineType = typeSolid;
    //那個(gè)圈的圖片偶洋,也可以自己畫熟吏,我這里就用圖片
    private Bitmap imgBitmap;

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

    public ProLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    LayoutParams lp;

    private void init() {
        imgBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pro_readed);
                //將線添加到 LinearLayout 的左邊,并設(shè)置一些邊距,這里注意一點(diǎn)就是 LayoutParams 第二個(gè)參數(shù)牵寺,如果平時(shí)正常情況悍引,
                //可以使用 LayoutParams.WRAP_CONTENT,但如果外層有使用 ScrollView 帽氓,就要使用 LayoutParams.MATCH_PARENT趣斤,
                //不然控件就會(huì)展不開,就會(huì)不顯示黎休。
        mProLine = new ProLine(getContext());
        lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
        lp.rightMargin = todp(14);
        lp.leftMargin = todp(16);
        this.addView(mProLine, lp);
    }

    public ProLinearLayout setLineType(String lineType) {
        this.lineType = lineType;
        return this;
    }

    public ProLinearLayout setImageResources(int resId) {
        this.imgBitmap = BitmapFactory.decodeResource(getResources(), resId);
        return this;
    }

    public ProLinearLayout setIsLastOne(boolean isLastOne) {
        this.isLastOne = isLastOne;
        return this;
    }
    
    public ProLinearLayout setIsTopTypeDotted(boolean isTopTypeDotted) {
        this.isTopTypeDotted = isTopTypeDotted;
        return this;
    }

    public ProLinearLayout setIsTopOne(boolean isTopOne) {
        this.isTopOne = isTopOne;
        return this;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
         mProLine.setParentHeight(getMeasuredHeight());     //將 LinearLayout 的高度設(shè)置成左邊線的高度
            mProLine.setLineType(lineType).setImageBitmap(imgBitmap)
                    .setIsLastOne(isLastOne).setIsTopOne(isTopOne).setIsTopTypeDotted(isTopTypeDotted);
    }

    private int todp(int px) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, px, getResources().getDisplayMetrics());
    }
}

下面看左邊線的代碼:

public class ProLine extends View {

    private Paint mPaint;
    private Path path;
    private PathEffect effects;
    public final static String typeSolid = "solid";
    public final static String typeDotted = "dotted";
    private boolean isLastOne = false;
    private boolean isTopOne = false;
    private boolean isTopTypeDotted = false;

    private String lineType = typeSolid;
    private Bitmap imgBitmap;
    private int mParentHeight = 0;

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

    public ProLine(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        mPaint = new Paint();
        path = new Path();
        effects = new DashPathEffect(new float[] { 5, 5, 5, 5 }, 1);
        mPaint.setColor(Color.parseColor("#979797"));
        imgBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pro_readed);
    }

    public ProLine setLineType(String lineType) {
        this.lineType = lineType;
        return this;
    }

    public ProLine setImageBitmap(Bitmap bitmap) {
        this.imgBitmap = bitmap;
        return this;
    }

    public ProLine setIsLastOne(boolean isLastOne) {
        this.isLastOne = isLastOne;
        return this;
    }

    public void setParentHeight(int mParentHeight) {
        this.mParentHeight = mParentHeight;
        setMeasuredDimension(imgBitmap.getWidth(), this.mParentHeight);   //這里再設(shè)置一次是因?yàn)槿绻季謩?dòng)態(tài)改變(例如有個(gè)控件從隱藏到
                顯示狀態(tài))時(shí)浓领,左邊的線條高度不會(huì)變,還是原來(lái)的势腮,原因是 onMeasure 方法不調(diào)用联贩,所有無(wú)奈在這再寫一次,不知道怎么改捎拯。
    }

    public ProLine setIsTopTypeDotted(boolean isTopTypeDotted) {
        this.isTopTypeDotted = isTopTypeDotted;
        return this;
    }

    public ProLine setIsTopOne(boolean isTopOne) {
        this.isTopOne = isTopOne;
        return this;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
        if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(imgBitmap.getWidth(), mParentHeight); // 測(cè)量高度等于外層 LinearLayout 高度
        } else if (widthSpecMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(imgBitmap.getWidth(), heightSpecSize);
        } else if (heightSpecMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(widthSpecSize, mParentHeight); // 測(cè)量高度等于外層 LinearLayout 高度
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
                
  // 下面是各種判斷和各種畫圖 
               
        float startX = imgBitmap.getWidth() / 2;
        float stopX = startX;
        float startY = imgBitmap.getHeight();
        float stopY = mParentHeight;
        int paddingTop = todp(12);
        if (!isLastOne) {
            canvas.drawBitmap(imgBitmap, 0, paddingTop, mPaint);
            if (isTopOne) {
                canvas.drawLine(startX, startY, stopX, stopY, mPaint);
            } else {
                if (isTopTypeDotted && lineType.equals(typeSolid)) {
                    drawDottedLine(canvas, startX, 0, startX, paddingTop);
                    canvas.drawLine(startX, startY, stopX, stopY, mPaint);
                }
                if (!isTopTypeDotted && lineType.equals(typeSolid)) {
                    canvas.drawLine(startX, 0, stopX, paddingTop, mPaint);
                    canvas.drawLine(startX, startY, stopX, stopY, mPaint);
                }
                if (isTopTypeDotted && lineType.equals(typeDotted)) {
                    drawDottedLine(canvas, startX, 0, startX, paddingTop);
                    drawDottedLine(canvas, startX, startY, stopX, stopY);
                }
                if (!isTopTypeDotted && lineType.equals(typeDotted)) {
                    canvas.drawLine(startX, 0, stopX, paddingTop, mPaint);
                    drawDottedLine(canvas, startX, startY, stopX, stopY);
                }
            }
        } else {
            canvas.drawBitmap(imgBitmap, 0, stopY - startY - paddingTop, mPaint);
            if (lineType.equals(typeSolid)) {
                canvas.drawLine(startX, 0, stopX, stopY - startY - paddingTop, mPaint);
            } else if (lineType.equals(typeDotted)) {
                drawDottedLine(canvas, startX, 0, stopX, stopY - startY - paddingTop);
            }
        }
    }

    private void drawDottedLine(Canvas canvas, float startX, float startY, float stopX, float stopY) {
        mPaint.setStyle(Paint.Style.STROKE);
        path.moveTo(startX, startY);
        path.lineTo(stopX, stopY);
        mPaint.setPathEffect(effects);
        canvas.drawPath(path, mPaint);
    }

    private int todp(int px) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, px, getResources().getDisplayMetrics());
    }

用法:

   <com.text.lzx.ProLinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content" >
   </com.text.lzx.ProLinearLayout>

java 代碼中要設(shè)置的話就各種 set 方法就行泪幌。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌岸裙,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,807評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浴滴,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡岁钓,警方通過(guò)查閱死者的電腦和手機(jī)升略,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)屡限,“玉大人品嚣,你說(shuō)我怎么就攤上這事【螅” “怎么了翰撑?”我有些...
    開封第一講書人閱讀 169,589評(píng)論 0 363
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)啊央。 經(jīng)常有香客問(wèn)我眶诈,道長(zhǎng),這世上最難降的妖魔是什么瓜饥? 我笑而不...
    開封第一講書人閱讀 60,188評(píng)論 1 300
  • 正文 為了忘掉前任逝撬,我火速辦了婚禮,結(jié)果婚禮上乓土,老公的妹妹穿的比我還像新娘宪潮。我一直安慰自己溯警,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,185評(píng)論 6 398
  • 文/花漫 我一把揭開白布狡相。 她就那樣靜靜地躺著梯轻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪尽棕。 梳的紋絲不亂的頭發(fā)上喳挑,一...
    開封第一講書人閱讀 52,785評(píng)論 1 314
  • 那天,我揣著相機(jī)與錄音滔悉,去河邊找鬼伊诵。 笑死,一個(gè)胖子當(dāng)著我的面吹牛氧敢,可吹牛的內(nèi)容都是我干的日戈。 我是一名探鬼主播询张,決...
    沈念sama閱讀 41,220評(píng)論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼孙乖,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了份氧?” 一聲冷哼從身側(cè)響起唯袄,我...
    開封第一講書人閱讀 40,167評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蜗帜,沒(méi)想到半個(gè)月后恋拷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,698評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡厅缺,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,767評(píng)論 3 343
  • 正文 我和宋清朗相戀三年蔬顾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片湘捎。...
    茶點(diǎn)故事閱讀 40,912評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡诀豁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出窥妇,到底是詐尸還是另有隱情舷胜,我是刑警寧澤,帶...
    沈念sama閱讀 36,572評(píng)論 5 351
  • 正文 年R本政府宣布活翩,位于F島的核電站烹骨,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏材泄。R本人自食惡果不足惜沮焕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,254評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拉宗。 院中可真熱鬧遇汞,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至歪赢,卻和暖如春化戳,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背埋凯。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工点楼, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人白对。 一個(gè)月前我還...
    沈念sama閱讀 49,359評(píng)論 3 379
  • 正文 我出身青樓掠廓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親甩恼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蟀瞧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,922評(píng)論 2 361

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