1. package com.dwood.paintdemo;
2.
3. import android.app.Dialog;
4. import android.content.Context;
5. import android.graphics.Canvas;
6. import android.graphics.Color;
7. import android.graphics.LinearGradient;
8. import android.graphics.Paint;
9. import android.graphics.RectF;
10. import android.graphics.Shader;
11. import android.graphics.SweepGradient;
12. import android.os.Bundle;
13. import android.util.Log;
14. import android.view.MotionEvent;
15. import android.view.View;
16. import android.view.WindowManager;
17.
18. public class ColorPickerDialog extends Dialog {
19. private final boolean debug = true;
20. private final String TAG = "ColorPicker";
21.
22. Context context;
23. private String title;//标题
24. private int mInitialColor;//初始颜色
25. private OnColorChangedListener mListener;
26.
27. /**
28. * 初始颜色黑色
29. * @param context
30. * @param title 对话框标题
31. * @param listener 回调
32. */
33. public ColorPickerDialog(Context context, String title,
34. OnColorChangedListener listener) {
35. this(context, Color.BLACK, title, listener);
36. }
37.
38. /**
39. *
40. * @param context
41. * @param initialColor 初始颜色
42. * @param title 标题
43. * @param listener 回调
44. */
45. public ColorPickerDialog(Context context, int initialColor,
46. String title, OnColorChangedListener listener) {
47. super(context);
48. this.context = context;
49. mListener = listener;
50. mInitialColor = initialColor;
51. this.title = title;
52. }
53.
54. @Override
55. protected void onCreate(Bundle savedInstanceState) {
56. super.onCreate(savedInstanceState);
57. WindowManager manager = getWindow().getWindowManager();
58. int height = (int) (manager.getDefaultDisplay().getHeight() * 0.5f);
59. int width = (int) (manager.getDefaultDisplay().getWidth() * 0.7f);
60. ColorPickerView myView = new ColorPickerView(context, height, width);
61. setContentView(myView);
62. setTitle(title);
63. }
64.
65. private class ColorPickerView extends View {
66. private Paint mPaint;//渐变色环画笔
67. private Paint mCenterPaint;//中间圆画笔
68. private Paint mLinePaint;//分隔线画笔
69. private Paint mRectPaint;//渐变方块画笔
70.
71. private Shader rectShader;//渐变方块渐变图像
72. private float rectLeft;//渐变方块左x坐标
73. private float rectTop;//渐变方块右x坐标
74. private float rectRight;//渐变方块上y坐标
75. private float rectBottom;//渐变方块下y坐标
76.
77. private final int[] mCircleColors;//渐变色环颜色
78. private final int[] mRectColors;//渐变方块颜色
79.
80. private int mHeight;//View高
81. private int mWidth;//View宽
82. private float r;//色环半径(paint中部)
83. private float centerRadius;//中心圆半径
84.
85. private boolean downInCircle = true;//按在渐变环上
86. private boolean downInRect;//按在渐变方块上
87. private boolean highlightCenter;//高亮
88. private boolean highlightCenterLittle;//微亮
89.
90. public ColorPickerView(Context context, int height, int width) {
91. super(context);
92. this.mHeight = height - 36;
93. this.mWidth = width;
94. setMinimumHeight(height - 36);
95. setMinimumWidth(width);
96.
97. //渐变色环参数
98. mCircleColors = new int[] {0xFFFF0000, 0xFFFF00FF, 0xFF0000FF,
99. 0xFF00FFFF, 0xFF00FF00,0xFFFFFF00, 0xFFFF0000};
100. Shader s = new SweepGradient(0, 0, mCircleColors, null);
101. mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
102. mPaint.setShader(s);
103. mPaint.setStyle(Paint.Style.STROKE);
104. mPaint.setStrokeWidth(50);
105. r = width / 2 * 0.7f - mPaint.getStrokeWidth() * 0.5f;
106.
107. //中心圆参数
108. mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
109. mCenterPaint.setColor(mInitialColor);
110. mCenterPaint.setStrokeWidth(5);
111. centerRadius = (r - mPaint.getStrokeWidth() / 2 ) * 0.7f;
112.
113. //边框参数
114. mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
115. mLinePaint.setColor(Color.parseColor("#72A1D1"));
116. mLinePaint.setStrokeWidth(4);
117.
118. //黑白渐变参数
119. mRectColors = new int[]{0xFF000000, mCenterPaint.getColor(), 0xFFFFFFFF};
120. mRectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
121. mRectPaint.setStrokeWidth(5);
122. rectLeft = -r - mPaint.getStrokeWidth() * 0.5f;
123. rectTop = r + mPaint.getStrokeWidth() * 0.5f +
124. mLinePaint.getStrokeMiter() * 0.5f + 15;
125. rectRight = r + mPaint.getStrokeWidth() * 0.5f;
126. rectBottom = rectTop + 50;
127. }
128.
129. @Override
130. protected void onDraw(Canvas canvas) {
131. //移动中心
132. canvas.translate(mWidth / 2, mHeight / 2 - 50);
133. //画中心圆
134. canvas.drawCircle(0, 0, centerRadius, mCenterPaint);
135. //是否显示中心圆外的小圆环
136. if (highlightCenter || highlightCenterLittle) {
137. int c = mCenterPaint.getColor();
138. mCenterPaint.setStyle(Paint.Style.STROKE);
139. if(highlightCenter) {
140. mCenterPaint.setAlpha(0xFF);
141. }else if(highlightCenterLittle) {
142. mCenterPaint.setAlpha(0x90);
143. }
144. canvas.drawCircle(0, 0,
145. centerRadius + mCenterPaint.getStrokeWidth(), mCenterPaint);
146.
147. mCenterPaint.setStyle(Paint.Style.FILL);
148. mCenterPaint.setColor(c);
149. }
150. //画色环
151. canvas.drawOval(new RectF(-r, -r, r, r), mPaint);
152. //画黑白渐变块
153. if(downInCircle) {
154. mRectColors[1] = mCenterPaint.getColor();
155. }
156. rectShader = new LinearGradient(rectLeft, 0, rectRight, 0, mRectColors, null, Shader.TileMode.MIRROR);
157. mRectPaint.setShader(rectShader);
158. canvas.drawRect(rectLeft, rectTop, rectRight, rectBottom, mRectPaint);
159. float offset = mLinePaint.getStrokeWidth() / 2;
160. canvas.drawLine(rectLeft - offset, rectTop - offset * 2,
161. rectLeft - offset, rectBottom + offset * 2, mLinePaint);//左
162. canvas.drawLine(rectLeft - offset * 2, rectTop - offset,
163. rectRight + offset * 2, rectTop - offset, mLinePaint);//上
164. canvas.drawLine(rectRight + offset, rectTop - offset * 2,
165. rectRight + offset, rectBottom + offset * 2, mLinePaint);//右
166. canvas.drawLine(rectLeft - offset * 2, rectBottom + offset,
167. rectRight + offset * 2, rectBottom + offset, mLinePaint);//下
168. super.onDraw(canvas);
169. }
170.
171. @Override
172. public boolean onTouchEvent(MotionEvent event) {
173. float x = event.getX() - mWidth / 2;
174. float y = event.getY() - mHeight / 2 + 50;
175. boolean inCircle = inColorCircle(x, y,
176. r + mPaint.getStrokeWidth() / 2, r - mPaint.getStrokeWidth() / 2);
177. boolean inCenter = inCenter(x, y, centerRadius);
178. boolean inRect = inRect(x, y);
179.
180. switch (event.getAction()) {
181. case MotionEvent.ACTION_DOWN:
182. downInCircle = inCircle;
183. downInRect = inRect;
184. highlightCenter = inCenter;
185. case MotionEvent.ACTION_MOVE:
186. if(downInCircle && inCircle) {//down按在渐变色环内, 且move也在渐变色环内
187. float angle = (float) Math.atan2(y, x);
188. float unit = (float) (angle / (2 * Math.PI));
189. if (unit < 0) {
190. unit += 1;
191. }
192. mCenterPaint.setColor(interpCircleColor(mCircleColors, unit));
193. if(debug) Log.v(TAG, "色环内, 坐标: " + x + "," + y);
194. }else if(downInRect && inRect) {//down在渐变方块内, 且move也在渐变方块内
195. mCenterPaint.setColor(interpRectColor(mRectColors, x));
196. }
197. if(debug) Log.v(TAG, "[MOVE] 高亮: " + highlightCenter + "微亮: " + highlightCenterLittle + " 中心: " + inCenter);
198. if((highlightCenter && inCenter) || (highlightCenterLittle && inCenter)) {//点击中心圆, 当前移动在中心圆
199. highlightCenter = true;
200. highlightCenterLittle = false;
201. } else if(highlightCenter || highlightCenterLittle) {//点击在中心圆, 当前移出中心圆
202. highlightCenter = false;
203. highlightCenterLittle = true;
204. } else {
205. highlightCenter = false;
206. highlightCenterLittle = false;
207. }
208. invalidate();
209. break;
210. case MotionEvent.ACTION_UP:
211. if(highlightCenter && inCenter) {//点击在中心圆, 且当前启动在中心圆
212. if(mListener != null) {
213. mListener.colorChanged(mCenterPaint.getColor());
214. ColorPickerDialog.this.dismiss();
215. }
216. }
217. if(downInCircle) {
218. downInCircle = false;
219. }
220. if(downInRect) {
221. downInRect = false;
222. }
223. if(highlightCenter) {
224. highlightCenter = false;
225. }
226. if(highlightCenterLittle) {
227. highlightCenterLittle = false;
228. }
229. invalidate();
230. break;
231. }
232. return true;
233. }
234.
235. @Override
236. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
237. super.onMeasure(mWidth, mHeight);
238. }
239.
240. /**
241. * 坐标是否在色环上
242. * @param x 坐标
243. * @param y 坐标
244. * @param outRadius 色环外半径
245. * @param inRadius 色环内半径
246. * @return
247. */
248. private boolean inColorCircle(float x, float y, float outRadius, float inRadius) {
249. double outCircle = Math.PI * outRadius * outRadius;
250. double inCircle = Math.PI * inRadius * inRadius;
251. double fingerCircle = Math.PI * (x * x + y * y);
252. if(fingerCircle < outCircle && fingerCircle > inCircle) {
253. return true;
254. }else {
255. return false;
256. }
257. }
258.
259. /**
260. * 坐标是否在中心圆上
261. * @param x 坐标
262. * @param y 坐标
263. * @param centerRadius 圆半径
264. * @return
265. */
266. private boolean inCenter(float x, float y, float centerRadius) {
267. double centerCircle = Math.PI * centerRadius * centerRadius;
268. double fingerCircle = Math.PI * (x * x + y * y);
269. if(fingerCircle < centerCircle) {
270. return true;
271. }else {
272. return false;
273. }
274. }
275.
276. /**
277. * 坐标是否在渐变色中
278. * @param x
279. * @param y
280. * @return
281. */
282. private boolean inRect(float x, float y) {
283. if( x <= rectRight && x >=rectLeft && y <= rectBottom && y >=rectTop) {
284. return true;
285. } else {
286. return false;
287. }
288. }
289.
290. /**
291. * 获取圆环上颜色
292. * @param colors
293. * @param unit
294. * @return
295. */
296. private int interpCircleColor(int colors[], float unit) {
297. if (unit <= 0) {
298. return colors[0];
299. }
300. if (unit >= 1) {
301. return colors[colors.length - 1];
302. }
303.
304. float p = unit * (colors.length - 1);
305. int i = (int)p;
306. p -= i;
307.
308. // now p is just the fractional part [0...1) and i is the index
309. int c0 = colors[i];
310. int c1 = colors[i+1];
311. int a = ave(Color.alpha(c0), Color.alpha(c1), p);
312. int r = ave(Color.red(c0), Color.red(c1), p);
313. int g = ave(Color.green(c0), Color.green(c1), p);
314. int b = ave(Color.blue(c0), Color.blue(c1), p);
315.
316. return Color.argb(a, r, g, b);
317. }
318.
319. /**
320. * 获取渐变块上颜色
321. * @param colors
322. * @param x
323. * @return
324. */
325. private int interpRectColor(int colors[], float x) {
326. int a, r, g, b, c0, c1;
327. float p;
328. if (x < 0) {
329. c0 = colors[0];
330. c1 = colors[1];
331. p = (x + rectRight) / rectRight;
332. } else {
333. c0 = colors[1];
334. c1 = colors[2];
335. p = x / rectRight;
336. }
337. a = ave(Color.alpha(c0), Color.alpha(c1), p);
338. r = ave(Color.red(c0), Color.red(c1), p);
339. g = ave(Color.green(c0), Color.green(c1), p);
340. b = ave(Color.blue(c0), Color.blue(c1), p);
341. return Color.argb(a, r, g, b);
342. }
343.
344. private int ave(int s, int d, float p) {
345. return s + Math.round(p * (d - s));
346. }
347. }
348.
349. /**
350. * 回调接口
351. * @author <a href=" clarkamx@gmail.com">LynK</a >
352. *
353. * Create on 2012-1-6 上午8:21:05
354. *
355. */
356. public interface OnColorChangedListener {
357. /**
358. * 回调函数
359. * @param color 选中的颜色
360. */
361. void colorChanged(int color);
362. }
363.
364. public String getTitle() {
365. return title;
366. }
367.
368. public void setTitle(String title) {
369. this.title = title;
370. }
371.
372. public int getmInitialColor() {
373. return mInitialColor;
374. }
375.
376. public void setmInitialColor(int mInitialColor) {
377. this.mInitialColor = mInitialColor;
378. }
379.
380. public OnColorChangedListener getmListener() {
381. return mListener;
382. }
383.
384. public void setmListener(OnColorChangedListener mListener) {
385. this.mListener = mListener;
386. }
387. }
测试界面
PaintDemoActivity.java
Java 代码
1. package com.dwood.paintdemo;
2.
3. import android.app.Activity;
4. import android.content.Context;
5. import android.os.Bundle;
6. import android.view.View;
7. import android.widget.Button;
8. import android.widget.TextView;
9.
10. public class PaintDemoActivity extends Activity {
11. Context context;
12. private Button btnColorPicker;
13. private TextView tvText;
14.
15. private ColorPickerDialog dialog;
16.
17. @Override
18. public void onCreate(Bundle savedInstanceState) {
19. context = this;
20. super.onCreate(savedInstanceState);
21. setContentView(R.layout.main);
22. initViews();
23. }
24. /**
25. * 初始化UI
26. */
27. private void initViews() {
28. btnColorPicker = (Button) findViewById(R.id.btn_color_picker);
29. btnColorPicker.setOnClickListener(new View.OnClickListener() {
30.
31. @Override
32. public void onClick(View v) {
33. dialog = new ColorPickerDialog(context, tvText.getTextColors().getDefaultColor(),
34. getResources().getString(R.string.btn_color_picker),
35. new ColorPickerDialog.OnColorChangedListener() {
36.
37. @Override
38. public void colorChanged(int color) {
39. tvText.setTextColor(color);
40. }
41. });
42. dialog.show();
43. }
44. });
45. tvText = (TextView) findViewById(R.id.tv_text);
46. }
47. }
2.
3. import android.app.Dialog;
4. import android.content.Context;
5. import android.graphics.Canvas;
6. import android.graphics.Color;
7. import android.graphics.LinearGradient;
8. import android.graphics.Paint;
9. import android.graphics.RectF;
10. import android.graphics.Shader;
11. import android.graphics.SweepGradient;
12. import android.os.Bundle;
13. import android.util.Log;
14. import android.view.MotionEvent;
15. import android.view.View;
16. import android.view.WindowManager;
17.
18. public class ColorPickerDialog extends Dialog {
19. private final boolean debug = true;
20. private final String TAG = "ColorPicker";
21.
22. Context context;
23. private String title;//标题
24. private int mInitialColor;//初始颜色
25. private OnColorChangedListener mListener;
26.
27. /**
28. * 初始颜色黑色
29. * @param context
30. * @param title 对话框标题
31. * @param listener 回调
32. */
33. public ColorPickerDialog(Context context, String title,
34. OnColorChangedListener listener) {
35. this(context, Color.BLACK, title, listener);
36. }
37.
38. /**
39. *
40. * @param context
41. * @param initialColor 初始颜色
42. * @param title 标题
43. * @param listener 回调
44. */
45. public ColorPickerDialog(Context context, int initialColor,
46. String title, OnColorChangedListener listener) {
47. super(context);
48. this.context = context;
49. mListener = listener;
50. mInitialColor = initialColor;
51. this.title = title;
52. }
53.
54. @Override
55. protected void onCreate(Bundle savedInstanceState) {
56. super.onCreate(savedInstanceState);
57. WindowManager manager = getWindow().getWindowManager();
58. int height = (int) (manager.getDefaultDisplay().getHeight() * 0.5f);
59. int width = (int) (manager.getDefaultDisplay().getWidth() * 0.7f);
60. ColorPickerView myView = new ColorPickerView(context, height, width);
61. setContentView(myView);
62. setTitle(title);
63. }
64.
65. private class ColorPickerView extends View {
66. private Paint mPaint;//渐变色环画笔
67. private Paint mCenterPaint;//中间圆画笔
68. private Paint mLinePaint;//分隔线画笔
69. private Paint mRectPaint;//渐变方块画笔
70.
71. private Shader rectShader;//渐变方块渐变图像
72. private float rectLeft;//渐变方块左x坐标
73. private float rectTop;//渐变方块右x坐标
74. private float rectRight;//渐变方块上y坐标
75. private float rectBottom;//渐变方块下y坐标
76.
77. private final int[] mCircleColors;//渐变色环颜色
78. private final int[] mRectColors;//渐变方块颜色
79.
80. private int mHeight;//View高
81. private int mWidth;//View宽
82. private float r;//色环半径(paint中部)
83. private float centerRadius;//中心圆半径
84.
85. private boolean downInCircle = true;//按在渐变环上
86. private boolean downInRect;//按在渐变方块上
87. private boolean highlightCenter;//高亮
88. private boolean highlightCenterLittle;//微亮
89.
90. public ColorPickerView(Context context, int height, int width) {
91. super(context);
92. this.mHeight = height - 36;
93. this.mWidth = width;
94. setMinimumHeight(height - 36);
95. setMinimumWidth(width);
96.
97. //渐变色环参数
98. mCircleColors = new int[] {0xFFFF0000, 0xFFFF00FF, 0xFF0000FF,
99. 0xFF00FFFF, 0xFF00FF00,0xFFFFFF00, 0xFFFF0000};
100. Shader s = new SweepGradient(0, 0, mCircleColors, null);
101. mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
102. mPaint.setShader(s);
103. mPaint.setStyle(Paint.Style.STROKE);
104. mPaint.setStrokeWidth(50);
105. r = width / 2 * 0.7f - mPaint.getStrokeWidth() * 0.5f;
106.
107. //中心圆参数
108. mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
109. mCenterPaint.setColor(mInitialColor);
110. mCenterPaint.setStrokeWidth(5);
111. centerRadius = (r - mPaint.getStrokeWidth() / 2 ) * 0.7f;
112.
113. //边框参数
114. mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
115. mLinePaint.setColor(Color.parseColor("#72A1D1"));
116. mLinePaint.setStrokeWidth(4);
117.
118. //黑白渐变参数
119. mRectColors = new int[]{0xFF000000, mCenterPaint.getColor(), 0xFFFFFFFF};
120. mRectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
121. mRectPaint.setStrokeWidth(5);
122. rectLeft = -r - mPaint.getStrokeWidth() * 0.5f;
123. rectTop = r + mPaint.getStrokeWidth() * 0.5f +
124. mLinePaint.getStrokeMiter() * 0.5f + 15;
125. rectRight = r + mPaint.getStrokeWidth() * 0.5f;
126. rectBottom = rectTop + 50;
127. }
128.
129. @Override
130. protected void onDraw(Canvas canvas) {
131. //移动中心
132. canvas.translate(mWidth / 2, mHeight / 2 - 50);
133. //画中心圆
134. canvas.drawCircle(0, 0, centerRadius, mCenterPaint);
135. //是否显示中心圆外的小圆环
136. if (highlightCenter || highlightCenterLittle) {
137. int c = mCenterPaint.getColor();
138. mCenterPaint.setStyle(Paint.Style.STROKE);
139. if(highlightCenter) {
140. mCenterPaint.setAlpha(0xFF);
141. }else if(highlightCenterLittle) {
142. mCenterPaint.setAlpha(0x90);
143. }
144. canvas.drawCircle(0, 0,
145. centerRadius + mCenterPaint.getStrokeWidth(), mCenterPaint);
146.
147. mCenterPaint.setStyle(Paint.Style.FILL);
148. mCenterPaint.setColor(c);
149. }
150. //画色环
151. canvas.drawOval(new RectF(-r, -r, r, r), mPaint);
152. //画黑白渐变块
153. if(downInCircle) {
154. mRectColors[1] = mCenterPaint.getColor();
155. }
156. rectShader = new LinearGradient(rectLeft, 0, rectRight, 0, mRectColors, null, Shader.TileMode.MIRROR);
157. mRectPaint.setShader(rectShader);
158. canvas.drawRect(rectLeft, rectTop, rectRight, rectBottom, mRectPaint);
159. float offset = mLinePaint.getStrokeWidth() / 2;
160. canvas.drawLine(rectLeft - offset, rectTop - offset * 2,
161. rectLeft - offset, rectBottom + offset * 2, mLinePaint);//左
162. canvas.drawLine(rectLeft - offset * 2, rectTop - offset,
163. rectRight + offset * 2, rectTop - offset, mLinePaint);//上
164. canvas.drawLine(rectRight + offset, rectTop - offset * 2,
165. rectRight + offset, rectBottom + offset * 2, mLinePaint);//右
166. canvas.drawLine(rectLeft - offset * 2, rectBottom + offset,
167. rectRight + offset * 2, rectBottom + offset, mLinePaint);//下
168. super.onDraw(canvas);
169. }
170.
171. @Override
172. public boolean onTouchEvent(MotionEvent event) {
173. float x = event.getX() - mWidth / 2;
174. float y = event.getY() - mHeight / 2 + 50;
175. boolean inCircle = inColorCircle(x, y,
176. r + mPaint.getStrokeWidth() / 2, r - mPaint.getStrokeWidth() / 2);
177. boolean inCenter = inCenter(x, y, centerRadius);
178. boolean inRect = inRect(x, y);
179.
180. switch (event.getAction()) {
181. case MotionEvent.ACTION_DOWN:
182. downInCircle = inCircle;
183. downInRect = inRect;
184. highlightCenter = inCenter;
185. case MotionEvent.ACTION_MOVE:
186. if(downInCircle && inCircle) {//down按在渐变色环内, 且move也在渐变色环内
187. float angle = (float) Math.atan2(y, x);
188. float unit = (float) (angle / (2 * Math.PI));
189. if (unit < 0) {
190. unit += 1;
191. }
192. mCenterPaint.setColor(interpCircleColor(mCircleColors, unit));
193. if(debug) Log.v(TAG, "色环内, 坐标: " + x + "," + y);
194. }else if(downInRect && inRect) {//down在渐变方块内, 且move也在渐变方块内
195. mCenterPaint.setColor(interpRectColor(mRectColors, x));
196. }
197. if(debug) Log.v(TAG, "[MOVE] 高亮: " + highlightCenter + "微亮: " + highlightCenterLittle + " 中心: " + inCenter);
198. if((highlightCenter && inCenter) || (highlightCenterLittle && inCenter)) {//点击中心圆, 当前移动在中心圆
199. highlightCenter = true;
200. highlightCenterLittle = false;
201. } else if(highlightCenter || highlightCenterLittle) {//点击在中心圆, 当前移出中心圆
202. highlightCenter = false;
203. highlightCenterLittle = true;
204. } else {
205. highlightCenter = false;
206. highlightCenterLittle = false;
207. }
208. invalidate();
209. break;
210. case MotionEvent.ACTION_UP:
211. if(highlightCenter && inCenter) {//点击在中心圆, 且当前启动在中心圆
212. if(mListener != null) {
213. mListener.colorChanged(mCenterPaint.getColor());
214. ColorPickerDialog.this.dismiss();
215. }
216. }
217. if(downInCircle) {
218. downInCircle = false;
219. }
220. if(downInRect) {
221. downInRect = false;
222. }
223. if(highlightCenter) {
224. highlightCenter = false;
225. }
226. if(highlightCenterLittle) {
227. highlightCenterLittle = false;
228. }
229. invalidate();
230. break;
231. }
232. return true;
233. }
234.
235. @Override
236. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
237. super.onMeasure(mWidth, mHeight);
238. }
239.
240. /**
241. * 坐标是否在色环上
242. * @param x 坐标
243. * @param y 坐标
244. * @param outRadius 色环外半径
245. * @param inRadius 色环内半径
246. * @return
247. */
248. private boolean inColorCircle(float x, float y, float outRadius, float inRadius) {
249. double outCircle = Math.PI * outRadius * outRadius;
250. double inCircle = Math.PI * inRadius * inRadius;
251. double fingerCircle = Math.PI * (x * x + y * y);
252. if(fingerCircle < outCircle && fingerCircle > inCircle) {
253. return true;
254. }else {
255. return false;
256. }
257. }
258.
259. /**
260. * 坐标是否在中心圆上
261. * @param x 坐标
262. * @param y 坐标
263. * @param centerRadius 圆半径
264. * @return
265. */
266. private boolean inCenter(float x, float y, float centerRadius) {
267. double centerCircle = Math.PI * centerRadius * centerRadius;
268. double fingerCircle = Math.PI * (x * x + y * y);
269. if(fingerCircle < centerCircle) {
270. return true;
271. }else {
272. return false;
273. }
274. }
275.
276. /**
277. * 坐标是否在渐变色中
278. * @param x
279. * @param y
280. * @return
281. */
282. private boolean inRect(float x, float y) {
283. if( x <= rectRight && x >=rectLeft && y <= rectBottom && y >=rectTop) {
284. return true;
285. } else {
286. return false;
287. }
288. }
289.
290. /**
291. * 获取圆环上颜色
292. * @param colors
293. * @param unit
294. * @return
295. */
296. private int interpCircleColor(int colors[], float unit) {
297. if (unit <= 0) {
298. return colors[0];
299. }
300. if (unit >= 1) {
301. return colors[colors.length - 1];
302. }
303.
304. float p = unit * (colors.length - 1);
305. int i = (int)p;
306. p -= i;
307.
308. // now p is just the fractional part [0...1) and i is the index
309. int c0 = colors[i];
310. int c1 = colors[i+1];
311. int a = ave(Color.alpha(c0), Color.alpha(c1), p);
312. int r = ave(Color.red(c0), Color.red(c1), p);
313. int g = ave(Color.green(c0), Color.green(c1), p);
314. int b = ave(Color.blue(c0), Color.blue(c1), p);
315.
316. return Color.argb(a, r, g, b);
317. }
318.
319. /**
320. * 获取渐变块上颜色
321. * @param colors
322. * @param x
323. * @return
324. */
325. private int interpRectColor(int colors[], float x) {
326. int a, r, g, b, c0, c1;
327. float p;
328. if (x < 0) {
329. c0 = colors[0];
330. c1 = colors[1];
331. p = (x + rectRight) / rectRight;
332. } else {
333. c0 = colors[1];
334. c1 = colors[2];
335. p = x / rectRight;
336. }
337. a = ave(Color.alpha(c0), Color.alpha(c1), p);
338. r = ave(Color.red(c0), Color.red(c1), p);
339. g = ave(Color.green(c0), Color.green(c1), p);
340. b = ave(Color.blue(c0), Color.blue(c1), p);
341. return Color.argb(a, r, g, b);
342. }
343.
344. private int ave(int s, int d, float p) {
345. return s + Math.round(p * (d - s));
346. }
347. }
348.
349. /**
350. * 回调接口
351. * @author <a href=" clarkamx@gmail.com">LynK</a >
352. *
353. * Create on 2012-1-6 上午8:21:05
354. *
355. */
356. public interface OnColorChangedListener {
357. /**
358. * 回调函数
359. * @param color 选中的颜色
360. */
361. void colorChanged(int color);
362. }
363.
364. public String getTitle() {
365. return title;
366. }
367.
368. public void setTitle(String title) {
369. this.title = title;
370. }
371.
372. public int getmInitialColor() {
373. return mInitialColor;
374. }
375.
376. public void setmInitialColor(int mInitialColor) {
377. this.mInitialColor = mInitialColor;
378. }
379.
380. public OnColorChangedListener getmListener() {
381. return mListener;
382. }
383.
384. public void setmListener(OnColorChangedListener mListener) {
385. this.mListener = mListener;
386. }
387. }
测试界面
PaintDemoActivity.java
Java 代码
1. package com.dwood.paintdemo;
2.
3. import android.app.Activity;
4. import android.content.Context;
5. import android.os.Bundle;
6. import android.view.View;
7. import android.widget.Button;
8. import android.widget.TextView;
9.
10. public class PaintDemoActivity extends Activity {
11. Context context;
12. private Button btnColorPicker;
13. private TextView tvText;
14.
15. private ColorPickerDialog dialog;
16.
17. @Override
18. public void onCreate(Bundle savedInstanceState) {
19. context = this;
20. super.onCreate(savedInstanceState);
21. setContentView(R.layout.main);
22. initViews();
23. }
24. /**
25. * 初始化UI
26. */
27. private void initViews() {
28. btnColorPicker = (Button) findViewById(R.id.btn_color_picker);
29. btnColorPicker.setOnClickListener(new View.OnClickListener() {
30.
31. @Override
32. public void onClick(View v) {
33. dialog = new ColorPickerDialog(context, tvText.getTextColors().getDefaultColor(),
34. getResources().getString(R.string.btn_color_picker),
35. new ColorPickerDialog.OnColorChangedListener() {
36.
37. @Override
38. public void colorChanged(int color) {
39. tvText.setTextColor(color);
40. }
41. });
42. dialog.show();
43. }
44. });
45. tvText = (TextView) findViewById(R.id.tv_text);
46. }
47. }