1. 程式人生 > >Android自定義View之仿京東售後稽核進度

Android自定義View之仿京東售後稽核進度

本篇文章已授權微信公眾號 guolin_blog (郭霖)獨家釋出

概述:同常在做商城類的App時,都會有售後的需求,而售後流程通常會因為不同的業務,而分為不確定的幾個步驟,如下圖所示:這裡寫圖片描述

那麼問題就來了,像這樣的效果如何實現呢?讓我們先放下這個問題,先看看UI模仿的京東原圖是怎樣的:

這裡寫圖片描述

最後在看看我最終實現的效果:

靜圖:三個步驟時,居中顯示

動圖:這裡寫圖片描述

從上面的效果圖中我們可以觀察到,當步驟少於等於5個時,等分居中顯示,當步驟大於5個時,可以橫向拖動顯示。

一 分析

1 需要實現的效果:相信不要多言,上面已經完全展示。

2 需要注意的點:步驟不固定,文字和圖片居中對齊,文字可能多行,多行的文字也是對稱的。

二 思路

相同的效果,會有不同的實現思路。這裡提供兩個方法實現:

1 將一個步驟單獨作為自定義view實現。

2 將所有步驟做為自定義view實現。

本文將才用第一種實現方式,實現我們的效果。將一個步驟作為自定義view時,我們還可以再分成三個部分: 左邊線,中間圖片,右邊線。

三 實現

1 自定義屬性:

   <declare-styleable name="AuditProgressView">
        <!--當前步驟是否完成 -->
        <attr name="apv_isCurrentComplete"
format="boolean" />
<!--下一個步驟是否完成 --> <attr name="apv_isNextComplete" format="boolean" /> <!--是不是第一個步驟 --> <attr name="apv_isFirstStep" format="boolean" /> <!--是不是最後一個步驟 --> <attr name="apv_isLastStep" format="boolean"
/>
<!--共有幾個步驟 --> <attr name="apv_stepCount" format="integer" /> <!--步驟提示 --> <attr name="apv_text" format="string|reference" /> </declare-styleable>

上面的屬性是必須定義的屬性。對於其他例如文字顏色 線條顏色 文字大小之類的屬性都沒有定義,有需要的可以自己下載原始碼進行修改。

2 onMeasue 方法的實現

   @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(widthMeasureSpec);

        // 在寬高不是精確模式時,定義最小寬高

        if (widthMode != MeasureSpec.EXACTLY) {
            width = getDisplayMetrics(getContext()).widthPixels / stepCount;
        }

        if (heightMode != MeasureSpec.EXACTLY) {
            height = dp2px(getContext(), 90);
        }
        setMeasuredDimension(width, height);
    }

onMeasue 方法中,在寬高不是精確模式時,設定最小寬高。而寬度的定義則涉及到 stepCount 屬性,是根據有幾個步驟,則將螢幕幾等分為最小寬度。需要注意的是,當自定view設計到 pading 和 margin 時 這裡的計算邏輯需要考慮 pading 和 marging 的位置。

3 onDraw 方法的實現

    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // 根據 當前步驟是否完成 確定中間的圖片
        if (mIsCurrentComplete) {
            audit_drawBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.audit_complete);
        } else {
            audit_drawBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.audit_uncomplete);
        }


        // 獲取自定義View的寬高
        width = getWidth();
        height = getHeight();

        // 繪製圖片
        canvas.drawBitmap(audit_drawBitmap, width / 2 - audit_drawBitmap.getWidth() / 2, height / 2 - audit_drawBitmap.getHeight() / 2, paint);

        // 根據當前步驟是否完成 確定繪製文字顏色
        String mString = text;
        TextPaint tp = new TextPaint();
        if (mIsCurrentComplete) {
            tp.setColor(Color.parseColor("#03A9F5"));
        } else {
            tp.setColor(Color.parseColor("#757575"));
        }

        // 繪製多行文字
        tp.setStyle(Paint.Style.FILL);
        Point point = new Point(width / 2, dp2px(getContext(), 70));
        tp.setTextSize(sp2px(getContext(), 14));
        textCenter(mString, tp, canvas, point, dp2px(getContext(), 57), Layout.Alignment.ALIGN_CENTER, 1, 0, false);

        // 繪製線條
        paint.setStrokeWidth(dp2px(getContext(), 2));

        // 根據是不是第一個步驟 確定是否有左邊線條
        if (!mIsFirstStep) {
            // 左邊
            // 根據當前步驟是否完成 來確定左邊線條的顏色
            if (mIsCurrentComplete) {
                paint.setColor(Color.parseColor("#03A9F5"));
            } else {
                paint.setColor(Color.parseColor("#E4E4E4"));
            }
            canvas.drawLine(0, height / 2, width / 2 - audit_drawBitmap.getWidth() / 2 - dp2px(getContext(), 8), height / 2, paint);
        }

        // 根據是不是最後的步驟 確定是否有右邊線條
        if (!mIsLastStep) {
            // 右邊
            // 根據下一個步驟是否完成 來確定右邊線條的顏色
            if (mIsNextComplete) {
                paint.setColor(Color.parseColor("#03A9F5"));
            } else {
                paint.setColor(Color.parseColor("#E4E4E4"));
            }
            canvas.drawLine(width / 2 + audit_drawBitmap.getWidth() / 2 + dp2px(getContext(), 8), height / 2, width, height / 2, paint);
        }


    }

    //繪製多行文字
    private void textCenter(String string, TextPaint textPaint, Canvas canvas, Point point, int width, Layout.Alignment align, float spacingmult, float spacingadd, boolean includepad) {
        StaticLayout staticLayout = new StaticLayout(string, textPaint, width, align, spacingmult, spacingadd, includepad);
        canvas.save();
        canvas.translate(-staticLayout.getWidth() / 2 + point.x, -staticLayout.getHeight() / 2 + point.y);
        staticLayout.draw(canvas);
        canvas.restore();
    }

a 根據 當前步驟是否完成 確定中間的圖片

b 根據當前步驟是否完成 確定繪製文字顏色

c 根據是不是第一個步驟 確定是否有左邊線條,再根據當前步驟是否完成 來確定左邊線條的顏色

d 根據是不是最後的步驟 確定是否有右邊線條,再根據下一個步驟是否完成 來確定右邊線條的顏色

e 繪製多行文字的具體實現。可以參考我部落格的關與自定義view的系列文章自定義view之drawText多行文字繪製

4 配合activity中動態使用新增的方法

   public void setIsCurrentComplete(boolean isCurrentComplete) {this.mIsCurrentComplete = isCurrentComplete;}

    public void setIsNextComplete(boolean isNextComplete) {
        this.mIsNextComplete = isNextComplete;
    }

    public void setIsFirstStep(boolean isFirstStep) {
        this.mIsFirstStep = isFirstStep;
    }

    public void setIsLastStep(boolean isLastStep) {
        this.mIsLastStep = isLastStep;
    }

    public void setText(String text) {
        this.text = text;
    }

    public void setStepCount(int stepCount) {
        this.stepCount = stepCount;
    }

四 原始碼

原始碼下載:github下載地址,覺得不錯的同學請start下,謝謝。

相關推薦

Android定義View仿京東售後稽核進度

本篇文章已授權微信公眾號 guolin_blog (郭霖)獨家釋出 概述:同常在做商城類的App時,都會有售後的需求,而售後流程通常會因為不同的業務,而分為不確定的幾個步驟,如下圖所示: 那麼問題就來了,像這樣的效果如何實現呢?讓我們先放下這個問題,先看

android定義View仿通訊錄側邊欄滑動,實現A-Z字母檢索

我們的手機通訊錄一般都有這樣的效果,如下圖: OK,這種效果大家都見得多了,基本上所有的android手機通訊錄都有這樣的效果。那我們今天就來看看這個效果該怎麼實現。 一.概述 1.頁面功能分析 整體上來說,左邊是一個ListView,右邊是一個自定義View,但

Android定義View仿QQ側滑選單實現

最近,由於正在做的一個應用中要用到側滑選單,所以通過查資料看視訊,學習了一下自定義View,實現一個類似於QQ的側滑選單,順便還將其封裝為自定義元件,可以實現類似QQ的側滑選單和抽屜式側滑選單兩種選單。 下面先放上效果圖: 我們這裡的側

Android 定義View仿華為圓形載入進度

效果圖 實現思路 可以看出該View可分為三個部分來實現 最外圍的圓,該部分需要區分進度圓和底部的刻度圓,進度部分的刻度需要和底色刻度區分開來 中間顯示的文字進度,需要讓文字在View中居中顯示 旋轉的小圓點,小圓點需要模擬小球下落運動時的加速度

Android定義view實現仿抖音雙擊點贊單擊暫停特效

       2018年抖音、快手、火山等短視訊App比較火,最近自己做短視訊專案時有個需求,就是類似抖音的點贊特效,單擊螢幕時視訊暫停,再次點選時視訊恢復播放,雙擊或者連續多次點選時出現點贊特效(飄小心心特效),而且是全屏可以隨意點選,都

Android定義View分貝儀

一、說明        最近在整理自定義View方面的知識,偶爾看到meizu工具箱的分貝儀效果,感覺它的實效效果還挺好的,遂想自己模擬實現練練手,廢話不多說,直接開擼。 二、效果圖 首先看一下效果圖: 看效果還挺炫酷

Android定義ViewCanvas

https://www.jianshu.com/p/fb18c28d6627 用繼承View的方式來自定義View,我們就需要重寫onDraw方法,也就是得咱自己來畫圖了。畫圖就得用到畫筆和畫布,也就是Paint和Canvas。我們來了解下Canvas。 Canvas Canvas我們可

Android 定義ViewCanvas詳解

自定義View的相關文章: Android 實現一個簡單的自定義View Android 自定義View步驟 Android Paint詳解 Android 自定義View之Canvas相關方法說明 Android 自定義View例項之 “京東跑”

Android : 定義View流式佈局

寫了一個很簡單的佈局 這是周圍圓框的drawable <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android">

Android定義ViewgetTextBounds()

在Android自定義View的過程中一定會用到Paint,而paint屬性中有一個方法getTextBounds(String text,int start,int end,Rext bounds),它的中文解釋是:返回一個包含中文的矩形邊界,位置為(start,end) 英文解釋:Retur

Android定義View定義屬性

在Android開發中經常會用到自定義View的情況,而在自定義View時,自定義屬性是必須用到的。 1、新建一個自定義View如CustomView 它的自定義屬性主要是通過declare-styleable標籤為其配置自定義屬性。具體做法是:在res/values/目錄下增加一個reso

Android -- 定義viewStepView

先看看實現的效果: 2,首先我們來看看我們常規的自定義view的基礎步驟吧         1,繼承View,重寫構造方法 2,自定義屬性 3,重寫onMeasure()測量控制元件高度 4,重寫onDra

Android 定義View 可隨意拖動的View

因為趕專案本人停更兩個月 從今天開始又可以更新了 今天說一下這個可隨意拖動的view 簡單說一下這個view效果 和 發展 一開始這種效果是使用在網頁端的特別是購物類 例如某寶 某東 購物車和客服視窗 都有使用這個懸浮可拖動的設計效果 後來才發展到的移動端 還有

定義View仿ios分段選擇器

一:效果 1.1 可動態新增或刪除tab,更改指定tab的文字。 二:實現思路 自定義view,實現效果 動態建立textview,有幾個tab建立幾個textview 第一個tab和最後一個tab為圓角矩形,其餘的為直角矩形,通過shape檔案完成 預設選

Android 定義View咖啡動畫

文章目錄效果畫杯子畫杯墊畫煙霧 效果 大概思路 自定義view,直接繼承view 複寫onSizeChanged()方法,在此計算杯墊,杯子,煙霧效果的path 在onDraw()方法中,描繪杯墊,杯子 處理煙霧動畫效果 畫杯子 這裡需要畫兩部分內容,第

Android 定義View下雨動畫

文章目錄效果思路畫雲畫雨滴優化 效果 開始前先做個熱身( ˘•灬•˘ ) 自己實現比較容易,但是到了要出部落格整理思路,總結要點的時候就撓頭,不知雲所以,所以最簡單的還是 如果對安卓UI有興趣的朋友可以加我好友互相探討, 思路 思路比較簡單,整個view無

android定義View定義EditText(新增刪除功能)

           忙忙碌碌20天,新的專案終於接近尾聲了。今天公司召集幾個使用者體驗師和美工一起吐糟這20天做的這個新產品,對於產品提出了很多建議,這幾天就改介面了。在這個專案中大量的使用了EditText元件,並且添加了刪除功能。這裡面都是用RelativeLayou

android定義view畫圓隨著手指移動

public class MyView extends View { private Paint mFanPaint,mTextPaint;//扇形畫筆和文字畫筆 public float AxisX=100; public float AxisY=100; public MyView(

Android定義view實現帶checkbox的Snackbar

前言 最近專案要求實現一個類似於snackbar功能,但是又不完全是snackbar的外掛,本來想在Google提供的snackbar裡面進行更改,但是這樣太麻煩了,於是自己動手實現了一個snackbar。先看下效果圖: 1.要解決的問題 1.彈框裡面除了文字提示之外還有一個按鈕,這個按

android定義View3D索引效果

效果圖: 我的小霸王太卡了。 最近工作比較忙,今天搞了一下午才搞出來這個效果,這種效果有很多種實現方式,最常見的應該是用貝塞爾曲線實現的。今天我們來看另一種不同的實現方式,只需要用到 canvas.scale(),有沒有很好奇是怎麼實現的呢。 首先來說一下思路,只要有了思