一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Android - Android自定義View實現顏色選取器

Android自定義View實現顏色選取器

2022-02-28 15:13DuanJiaNing_ Android

這篇文章主要為大家詳細介紹了Android自定義View實現顏色選取器 ,類似SeekBar的方式通過滑動選擇顏色,具有一定的參考價值,感興趣的小伙伴們可以參考一下

Android 自定義View 顏色選取器,可以實現水平、豎直選擇顏色類似 SeekBar 的方式通過滑動選擇顏色。

效果圖

Android自定義View實現顏色選取器

xml 屬性

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

使用

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

示例:

在 xml 中使用:

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

在 java 中使用:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
...
 @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
 
  }
 });
 }
...

實現解析

1 構成

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

Android自定義View實現顏色選取器

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

2 實現邏輯

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

2.1 onMeasure

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

2.2 onLayout

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

2.2.1 指示點坐標的確定:

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

2.2.2 顏色條邊界確定:

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

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

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

特殊情況:

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

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

解決方法:

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

不足:

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

2.2.3 為什么使用兩張 Bitmap

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

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

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

2.3 onDraw

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

代碼中寫了很多注釋,可以參照注釋理解。

已上傳 Github,可以在這里找到:DuanJiaNing/ColorPicker

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://blog.csdn.net/aimeimeiTS/article/details/77162143

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产精品99在线观看 | 日韩一区二区三区在线 | 国产日韩精品一区二区在线观看播放 | 美女日b视频 | 亚洲区精品久久一区二区三区 | 精品久久一 | 国产精品免费精品自在线观看 | 成人看片免费无限观看视频 | 97伊人久久精品亚洲午夜 | 朝鲜女人free性hu | 美女的让男人桶爽免费看 | 俺去啦最新地址 | 999久久精品国产 | 日本花季传媒2020旧版安卓 | 成人免费视频播放 | 蜜桃影像传媒破解版 | 国产一级黄色录像 | 久久久久久久久人体 | 日本护士撒尿xxxx欧美 | 91色爱 | 亚洲国产精品久久精品成人网站 | 精品一区二区三区高清免费观看 | 亚洲精品中文字幕第一区 | 日本片免费观看一区二区 | 国产视频二 | 性色AV乱码一区二区三区视频 | 亚洲免费视频一区二区三区 | 午夜伦理电影在线观免费 | 日韩欧美一区二区不卡 | 免费欧美一级片 | 人生路不在线观看完整版 | 好吊色青青青国产综合在线观看 | 欧美性xxxxxx爱 | 日本 在线观看 | 91无毒不卡 | 日韩一级精品视频在线观看 | 99在线在线视频免费视频观看 | 欧美精品一区二区三区免费播放 | 粗暴hd另类另类 | 免费理伦片高清在线 | 性色香蕉AV久久久天天网 |