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自定義View之Canvas
https://www.jianshu.com/p/fb18c28d6627 用繼承View的方式來自定義View,我們就需要重寫onDraw方法,也就是得咱自己來畫圖了。畫圖就得用到畫筆和畫布,也就是Paint和Canvas。我們來了解下Canvas。 Canvas Canvas我們可
Android 自定義View之Canvas詳解
自定義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自定義View之getTextBounds()
在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 -- 自定義view之StepView
先看看實現的效果: 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自定義View之3D索引效果
效果圖: 我的小霸王太卡了。 最近工作比較忙,今天搞了一下午才搞出來這個效果,這種效果有很多種實現方式,最常見的應該是用貝塞爾曲線實現的。今天我們來看另一種不同的實現方式,只需要用到 canvas.scale(),有沒有很好奇是怎麼實現的呢。 首先來說一下思路,只要有了思