牙叔教程 簡單易懂
效果展示
拾色器采用的是HSL顏色模型, 可以控制顏色的亮度和飽和度
同時還可以控制顏色的透明度
拾色器返回的數(shù)據(jù)如下
環(huán)境
手機: Mi 11 Pro
Android版本: 12
Autojs版本: 9.1.6
踩坑
一開始我用的是dialog, 可是寬高修改不了, 所以后來改成了PopupWindow
目的
我要用顏色選擇器的時候, 沒找到輪子, 所以就寫了這個拾色器;
把它做成通用的模塊, 讓所有人都可以輕松的選擇顏色
接口
ui.showColorPicker.on("click", () => {
colorPicker.show().then((color) => {
let result = "您選擇的顏色是:\n" + color;
log("result = " + result);
ui.info.text(result);
});
});
使用模塊的show方法, 就可以顯示拾色器, 點擊拾色器右下角的確定, 就會返回顏色數(shù)據(jù);
大家可以看到, 這里使用了then, 也就是說show方法返回的是一個promise;
為什么選擇promise
當拾色器顯示出來后, 你要花幾秒鐘選擇顏色, 然后點擊確定, 返回顏色;
不一定非要用promise, 但我覺得目前他是最合適的;
如果你用本地存儲, 廣播, 全局變量,都可以實現(xiàn), 但我覺得都會喪失這個拾色器模塊的獨立性
界面設(shè)計
我先畫了一個簡單的草稿
然后, 我要把它做成一個所有手機上, 視覺上都一樣的效果, 因此我使用了
layout_width="0dp" layout_weight="1"
寬高按照一定的比例來展示, 這樣所有手機看上去就都一樣了.
模塊設(shè)計
模塊有2個文件
colorPicker.js
CustomView.js
colorPicke負責展示一個自定義控件, 并且返回一個promise;
CustomView負責自定義控件的各種細節(jié).
依賴圖如下
可以看到還有一個縱向的滑塊VerticalSeekBar, 這是為了貼近HSL顏色模型;
所以把seekbar改成了縱向;
從HSL模型中, 可以看到, 飽和度是橫向的, 亮度就是縱向的:
界面細節(jié)
色輪
<View id="hueControlView"></View>
繪制View的前景或者背景, 都可以
setForeground
setBackgroundDrawable
var drawable = new android.graphics.drawable.Drawable({
draw: function (canvas) {
drawCircleGrid(canvas);
canvas.drawCircle(centerX, centerY, radius, colorWheelPaint);
drawSmallCircle(canvas, centerX, centerY, roadLength, roadAngle, smallCirclePaint);
},
});
// view.setBackgroundDrawable(drawable);
view.setForeground(drawable);
同時還要繪制小圓, 以及灰白格子, 畫筆設(shè)置了一個SweepGradientShader
確定按鈕
他的主要功能是顯示當前手指觸摸的顏色, 同時兼職確定按鈕的功能, 返回顏色;
他要繪制三個東西: 灰白格子, 當前顏色, 確定兩個字
灰白格子
是為了顯示顏色的透明效果
顏色數(shù)據(jù)
所有的顏色數(shù)據(jù)都基于HSL, 包括rgb也是由HSL轉(zhuǎn)換的
colorPicker.getArgbColor = function () {
let hsl = colorPicker.getHslColor();
let color = ColorUtils.HSLToColor(hsl);
let alpha = parseInt(colorPicker.hsla.alpha * 255);
color = ColorUtils.setAlphaComponent(color, alpha);
return color;
};
透明度是獨立的, 先得到顏色之后, 再添加顏色的透明度;
顏色范圍
hsla
h:0-360, s:0-1, l:0-1, a:0-1
argb
a:0-255, r:0-255, g:0-255, b:0-255
觸摸事件
在觸摸事件中, 我們要修改小圓的位置, 以及右下角確定按鈕的顏色;
hueControlView.setOnTouchListener(function (v, event) {
let x = event.getX();
let y = event.getY();
let distance = Math.sqrt(Math.pow(x - centerX, 2) + Math.pow(y - centerY, 2));
if (distance > radius - colorPicker.smallCircleRadius) {
distance = radius - colorPicker.smallCircleRadius;
}
let angle = Math.atan2(centerY - y, x - centerX); // angle是弧度
updateHslData(angle);
colorPicker.roadAngle = angle;
colorPicker.roadLength = distance;
refreshAllData(view);
return true;
});
所有的代碼 都盡量封裝成函數(shù), 方便復用;
在修改小圓位置的時候, 我們會計算他和中心的距離, 不讓他超過色輪的半徑;
同時我們在觸摸事件中, 要修改hsl中的色相h的值
三個滑塊
分別控制顏色的飽和度, 亮度, 和透明度,
左下角數(shù)據(jù)展示區(qū)
依序展示當前顏色的hsla和argb的值
相關(guān)教程
名人名言
思路是最重要的, 其他的百度, bing, stackoverflow, github, 安卓文檔, autojs文檔, 最后才是群里問問
--- 牙叔教程
聲明
部分內(nèi)容來自網(wǎng)絡(luò)
本教程僅用于學習, 禁止用于其他用途