上週同事問有沒有多個Item的Switch控件,我想這也不是什麼難事,這麼多第三方庫,直接挑一個就行。找了半天,雖然說大部分Switch都很炫,不過都只支持兩個Item,惟一找到的支持多Item的,可是是用在ios的,如圖: java
能夠從圖中看出,特色是:android
Github地址:github.com/mCyp/Orient…ios
製做這個Switch挺簡單,過程是:git
這也就是本Switch的難點了,如何繪製部分文字和圖標呢,答案就見標題了,使用畫布裁剪的方法Canvas.clipRect(Rect rect)
,我若是將畫布Canvas
裁剪成一個滑塊大小,這個時候,我再繪製滑塊覆蓋到的文字到原有的位置,超出滑塊的部分就不會顯示了。github
聰明的同窗這個時候可能會有這樣的疑問?你如今將畫布裁剪了,那豈不是隻能顯示滑塊了,道理是這樣的,但是咱們還有Canvas.save()
和Canvas.restore()
方法,它們對應的做用分別是將當前的畫布保存到對應的畫布棧中和取出畫布棧中頂層的畫布,並進行恢復。canvas
在這裏,我假設你們已經對基本的自定View已經很熟悉了,直接展現繪製滑塊的代碼:數組
/** * 繪製Switch滑動塊 */
private void drawThumb(Canvas canvas) {
// 滑塊的左右邊界
int left = mItemCoordinate[mThumbState.pos] + mThumbState.offset;
int right = mItemCoordinate[mThumbState.pos + 1] + mThumbState.offset;
// 1. 保存當前圖層
canvas.save();
Rect rect = new Rect(left + mThumbMargin, top + mThumbMargin, right - mThumbMargin, bottom - mThumbMargin);
// 2. 根據滑塊的設定大小裁剪畫布
canvas.clipRect(rect);
// 3. 繪製滑塊
int padding = mThumbMargin + mThumbBorderWidth;
if (mShape == SwitchShape.RECT) {
drawRoundRect(canvas, left + padding, top + padding
, right - padding, bottom - padding, CORNER_RADIUS, mThumbColorPaint);
if (mThumbBorderWidth != 0)
drawRoundRect(canvas, left + mThumbMargin, top + mThumbMargin
, right - mThumbMargin, bottom - mThumbMargin, CORNER_RADIUS, mThumbBorderPaint);
} else {
drawRoundRect(canvas, left + padding, top + padding
, right - padding, bottom - padding, (bottom - top) / 2 - padding, mThumbColorPaint);
if (mThumbBorderWidth != 0)
drawRoundRect(canvas, left + mThumbMargin, top + mThumbMargin
, right - mThumbMargin, bottom - mThumbMargin, (bottom - top) / 2 - mThumbMargin, mThumbBorderPaint);
}
int first, second;
//... 省略 獲取位置
// 4. 繪製文字orIcon
if (mType == SwitchType.TEXT) {
drawText(canvas, mItems[first], mItemCoordinate[first], top, mItemCoordinate[first + 1], bottom, mThumbTextPaint);
if (second != -1 && second <= mItemCount - 1) {
drawText(canvas, mItems[second], mItemCoordinate[second], top, mItemCoordinate[second + 1], bottom, mThumbTextPaint);
}
} else {
drawIcon(canvas, mIconRes[first], mItemCoordinate[first], top, mItemCoordinate[first + 1], bottom, mThumbTextPaint);
if (second >= 0) {
drawIcon(canvas, mIconRes[second], mItemCoordinate[second], top, mItemCoordinate[second + 1], bottom, mThumbTextPaint);
}
}
// 5. 底層的畫布恢復
canvas.restore();
}
複製代碼
註釋也都在上面了,對源碼感興趣的同窗能夠直接看Github,這個控件的代碼也就600行,處理好觸摸事件和使用好屬性動畫便可。bash
可能有的同窗不想關注原理,只想知道如何使用。微信
implementation 'com.orient:Orient-Ui:2.1.1'
複製代碼
<com.orient.me.widget.sw.MultiSwitch android:id="@+id/ms_weak" android:layout_width="match_parent" android:layout_marginStart="@dimen/len_10" android:layout_marginEnd="@dimen/len_10" android:layout_height="60dp" android:layout_gravity="center" android:layout_marginTop="@dimen/len_20" app:msBackgroundColor="@color/teal_300" app:msTextSize="@dimen/font_18" app:msNormalTextColor="@color/white_alpha_192" app:msShape="rect" app:msThumbColor="@color/white" app:msThumbMargin="@dimen/len_6" app:msThumbTextColor="@color/teal_300" app:msType="text" />
複製代碼
解釋一下各個屬性的用法:app
屬性 | 說明 | 類型 |
---|---|---|
msBackgroundColor | 背景顏色 | reference|color |
msNormalTextColor | 非選中狀態文本或者Icon顏色 | reference|color |
msThumbTextColor | 滑塊中文本或者Icon顏色 | reference|color |
msTextSize | 文本大小 | reference|dimension |
msIconSize | 圖標大小 | reference|dimension |
msThumbMargin | 滑塊的外邊距 | reference|dimension |
msShape | 選擇的形狀 | rect or oval |
msType | 選擇的類型 | text or icon |
msThumbColor | 滑塊背景色 | reference |
使用findViewById
獲取MultiSwitch
對象
設置字符串數組或者Icon數組
mHead.setItemsArray(new String[]{"Dark","Light"});
// or
mIconSwitch.setIconArray(new int[]{R.drawable.grid_ic_play,R.drawable.ic_camera,R.drawable.common_ic_back});
複製代碼
提供了位置選擇的回調以及滑塊移動百分比的回調,如個人效果圖,設置背景的黑夜模式和白天模式的時候,利用百分比回調能夠用來設置背景色的漸變效果。
mHead.setMultiSwitchListener(new MultiSwitchListener() {
@Override
public void onPositionSelected(int pos) {
// when pos selected, it will call back
}
@Override
public void onPositionOffsetPercent(int pos, float percent) {
// current page move offset percent when drag
}
});
複製代碼
除此之外,你還能夠設置默認位置:
// 設置默認位置
mHead.setCurrentItem(2);
複製代碼
進行自定View的時候,你們大可沒必要聞自定View色變,有的時候,某個自定義View的難點可能就是你們不經常使用到的那一到兩個Api,這個時候,就須要你們熟悉官方提供的Api了。
本人最近打算換工做了,在上海或者無錫,若是有好的公司推薦或者內推,能夠聯繫我哈,微信:Jw_19951030
,感激涕零~
若是你們對Oreint-Ui
系列的其餘控件感興趣,能夠查看: