溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么在Android中通過自定義View實現(xiàn)顏色選取器

發(fā)布時間:2021-05-14 17:37:04 來源:億速云 閱讀:151 作者:Leah 欄目:移動開發(fā)

怎么在Android中通過自定義View實現(xiàn)顏色選取器?針對這個問題,這篇文章詳細介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

xml 屬性

1.indicatorColor 指示點顏色
2.indicatorEnable 是否使用指示點
3.orientation 方向
horizontal 水平
vertical 豎直

使用

復制 \library\src…\ColorPickerView.java 和 \library\src\main\res\values\attrs.xml 文件到你的項目中,就可以在使用啦。

示例:

在 xml 中使用:

<com.duan.colorpicker.ColorPickerView <!--替換包名-->
 android:layout_width="50dp"
 android:layout_height="200dp"
 app:indicatorEnable="true"
 app:indicatorColor="#fff"
 app:orientation="vertical" />

在 java 中使用:

...
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);

 ColorPickerView picker = (ColorPickerView) findViewById(R.id.colorPickerView);
 picker.setIndicatorColor(Color.GREEN);
 picker.setOrientation(ColorPickerView.Orientation.HORIZONTAL);
 picker.setColors(Color.DKGRAY,Color.RED,Color.WHITE);
 picker.setOnColorPickerChangeListener(new ColorPickerView.OnColorPickerChangeListener() {
  @Override
  public void onColorChanged(ColorPickerView picker, int color) {
  // TODO
  }

  @Override
  public void onStartTrackingTouch(ColorPickerView picker) {
  // TODO

  }

  @Override
  public void onStopTrackingTouch(ColorPickerView picker) {
  // TODO

  }
 });
 }
...

實現(xiàn)解析

1 構(gòu)成

指示點:類似于 SeekBar 的滑塊,通過滑動指示點來選取顏色
顏色條:放置可選顏色

怎么在Android中通過自定義View實現(xiàn)顏色選取器

顏色條通過 Paint 的 setShader 方法,使用 LinearGradient 漸變色著色器繪制。
指示點只是普通的圓,不過加了陰影,使用 Paint 的 setShadowLayer 方法實現(xiàn),使用該方法時要關(guān)閉硬件加速。

2 實現(xiàn)邏輯

public class ColorPickerView extends View
控件繼承自 View。

2.1 onMeasure

onMeasure 方法完成控件大小的測量。控件定義了最小寬高,所以當指定控件寬高,且指定值小于最小寬高,則指定無效。

2.2 onLayout

onLayout 方法比較關(guān)鍵,在該方法中需要完成如下的任務(wù):
1. 計算出控件可用空間
2. 初始化指示點的坐標
3. 計算出顏色條的邊界
4. 設(shè)置顏色條的顏色(默認的漸變色)
4. 初始化兩張 Bitmap(一張用于繪制顏色條,一張用于繪制指示點)

2.2.1 指示點坐標的確定:

初始化時默認使指示點位于控件的中心,而后其位置由 onTouchEvent 方法控制,同時在 onTouchEvent 方法中進行重繪通知以及當前顏色選取。

2.2.2 顏色條邊界確定:

顏色條和指示點的大小比例計算方式:我將控件的可用空間(除去上下左右 padding 后剩余的空間)分為 9 份,這 9 份的分配方式是這樣的:
假設(shè)控件此時為水平方向,且寬度大于高度(這是一般的情況,在控件方向為水平,寬度小于高度時的情況下,邊界要進行特殊計算;控件方向為豎直,寬度大于高度的情況也需要特殊處理),取高度作為基數(shù)(取寬高中短的一邊作為基數(shù))進行平均分配,即: 高度 / 9 = 每一份的大小。

1/9 留白
2/9 指示點在顏色條上方的部分
3/9 顏色條高度
2/9 指示點在顏色條下方的部分
1/9 留白

這樣分之后就可以得出 圓的直徑占有 9 份中的 7 份,顏色條占有 3 份,兩份留白,這是高度的分配情況;顏色條的寬度滿足如下條件:在可用寬度的基礎(chǔ)上,左右分別留出指示點半徑的寬度,這是為了在指示點滑動到左右端點時留出空間給指示點顯示,同時保證指示點圓心能完整的掃過整個顏色條。豎直方向的測量計算邏輯也是一樣的。

特殊情況:

有兩種情況需要特殊處理
1. 控件為水平方向,此時控件的可用寬度小于可用高度。
2. 控件為豎直方向,此時控件的可用寬度大于可用高度。

這兩種情況的處理邏輯是一樣的,拿第一種情況舉例,若此時仍然以短邊(此時為寬)作為基數(shù)分為 9 份計算,左右分別留出圓半徑的寬度,此時圓直徑占有了控件可用寬的 7 / 9 ,而且顏色條左右分別留出 3.5 / 9(指示點半徑) 的空間,那么顏色條的寬度只剩 9 / 9 - ( 7 / 9) = 2/ 9 ,2 / 9 < 7 / 9,而且顏色條和指示點都是居中顯示的,這就導致指示點大部分遮擋甚至完全遮擋住顏色條。

解決方法:

針對第一種情況,此時使均分為 9 份的基數(shù)為寬(短邊)的 1 / 6(控件默認有個最小寬高,默認值的長邊與短邊之比就是 6 : 1)。
第二種情況下,使基數(shù)為高度的 1 / 6。

不足:

假設(shè)控件為水平方向,此時控件的可用寬度大于可用高度,但寬與高差值很小。這種情況下,指示點仍然有可能大部分遮擋甚至完全遮擋住顏色條,這種情況下并沒有進行處理,此時只能由使用者進行控制。經(jīng)過測試,在這種情況下(水平方向,寬大于高),當寬高比大于 3 : 1 時,顯示效果比較好,所以應(yīng)該盡量讓寬高比大于 3 : 1。豎直方向有同一的問題,不同的是,此時應(yīng)盡量使高與寬的比值大于 3 : 1.

2.2.3 為什么使用兩張 Bitmap

onDraw 方法并不是直接繪制圓角矩形,然后繪制指示點(圓),這樣做會使兩部分直接繪制在一張位圖上,相互覆蓋,不利于取得當前指示點所指顏色。因而使用兩張位圖,一張負責繪制顏色條,一張繪制指示點,onDraw 時分別繪制這兩張位圖,取色時獲取顏色條對應(yīng)位圖上像素點的顏色即可。

取得位圖上指定點顏色的方法是使用 Bitmap 的 getPixel(int x,int y) 方法,這個方法可以取得位圖上由 x,y 指定的點像素,根據(jù)這個像素可以解析出這個點的顏色。

同時這樣可以提高控件繪制效率,在大多數(shù)情況下顏色條上的可選顏色是不會變化的,此時可以將在可選顏色發(fā)生變化后生成的位圖直接繪制到控件上,而不需要再一次繪制這個位圖,指示點也如此,只需在選取顏色時(滑動指示點時)改變繪制指示點位圖的坐標即可,無需再次生成指示點的位圖。

2.3 onDraw

onDraw 方法負責繪制,繪制時判斷指示點對應(yīng)位圖和顏色條對應(yīng)位圖是否需要重繪,需要則重繪,后繪制兩張位圖到控件上,否則直接繪制兩張位圖到控件。

Android是什么

Android是一種基于Linux內(nèi)核的自由及開放源代碼的操作系統(tǒng),主要使用于移動設(shè)備,如智能手機和平板電腦,由美國Google公司和開放手機聯(lián)盟領(lǐng)導及開發(fā)。

關(guān)于怎么在Android中通過自定義View實現(xiàn)顏色選取器問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI