Android颜色选择器之案例解析

  次阅读 作者:智能小宝 来源:互联网 2016-01-06 19:18 我要评论(0)

因为画图板中需要使用颜色选择器. 去查了下api demo, 发现有现成的ColorPickerDialog, 但是功能比较简单, 主要是无法选择黑色和白色. 之后也去网上找了下, 倒是发现了几个, 但是用着感觉不太好.就想着自己重写个好了.

先上图

1.测试界面

2. 调色板对话框

3. 选择颜色

4.改变字体颜色

调色板对话框

ColorPickerDialog.java

package com.dwood.paintdemo; import android.app.Dialog; import android.content.Context;import android.graphics.Canvas; import android.graphics.Color; importandroid.graphics.LinearGradient; import android.graphics.Paint; importandroid.graphics.RectF; import android.graphics.Shader; importandroid.graphics.SweepGradient; import android.os.Bundle; import android.util.Log; importandroid.view.MotionEvent; import android.view.View; import android.view.WindowManager;public class ColorPickerDialog extends Dialog { private final boolean debug = true ; privatefinal String TAG = "ColorPicker" ; Context context; private String title; // 标题 private intmInitialColor; // 初始颜色 private OnColorChangedListener mListener; /** * 初始颜色黑色 *@param context * @param title 对话框标题 * @param listener 回调 */ publicColorPickerDialog(Context context, String title, OnColorChangedListener listener) { this(context, Color.BLACK, title, listener); } /** * * @param context * @param initialColor 初始颜色 * @param title 标题 * @param listener 回调 */ public ColorPickerDialog(Context context, intinitialColor, String title, OnColorChangedListener listener) { super (context); this.context =context; mListener = listener; mInitialColor = initialColor; this.title = title; } @Overrideprotected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); WindowManager manager = getWindow().getWindowManager(); int height = ( int) (manager.getDefaultDisplay().getHeight() * 0.5f ); int width = ( int) (manager.getDefaultDisplay().getWidth() * 0.7f ); ColorPickerView myView = newColorPickerView(context, height, width); setContentView(myView); setTitle(title); } privateclass ColorPickerView extends View { private Paint mPaint; // 渐变色环画笔 private Paint mCenterPaint; // 中间圆画笔 private Paint mLinePaint; // 分隔线画笔 private Paint mRectPaint;// 渐变方块画笔 private Shader rectShader; // 渐变方块渐变图像 private float rectLeft; // 渐变方块左x坐标 private float rectTop; // 渐变方块右x坐标 private float rectRight; // 渐变方块上y坐标private float rectBottom; // 渐变方块下y坐标 private final int[] mCircleColors; // 渐变色环颜色private final int[] mRectColors; // 渐变方块颜色 private int mHeight; // View高 private intmWidth; // View宽 private float r; // 色环半径(paint中部) private float centerRadius; // 中心圆半径 private boolean downInCircle = true; // 按在渐变环上 private boolean downInRect; // 按在渐变方块上 private boolean highlightCenter; // 高亮 private boolean highlightCenterLittle; //微亮 public ColorPickerView(Context context, int height, int width) { super (context);this.mHeight = height - 36 ; this.mWidth = width; setMinimumHeight(height - 36 ); setMinimumWidth(width); // 渐变色环参数 mCircleColors = new int[] {0xFFFF0000, 0xFFFF00FF, 0xFF0000FF , 0xFF00FFFF, 0xFF00FF00,0xFFFFFF00, 0xFFFF0000 }; Shader s = newSweepGradient(0, 0, mCircleColors, null ); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setShader(s); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(50 ); r = width / 2 * 0.7f - mPaint.getStrokeWidth() * 0.5f ; // 中心圆参数 mCenterPaint = newPaint(Paint.ANTI_ALIAS_FLAG); mCenterPaint.setColor(mInitialColor); mCenterPaint.setStrokeWidth(5 ); centerRadius = (r - mPaint.getStrokeWidth() / 2 ) * 0.7f ; //边框参数 mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG); mLinePaint.setColor(Color.parseColor("#72A1D1" )); mLinePaint.setStrokeWidth(4 ); // 黑白渐变参数 mRectColors = new int[]{0xFF000000, mCenterPaint.getColor(), 0xFFFFFFFF }; mRectPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mRectPaint.setStrokeWidth(5 ); rectLeft = -r - mPaint.getStrokeWidth() * 0.5f ; rectTop = r + mPaint.getStrokeWidth() * 0.5f +mLinePaint.getStrokeMiter() * 0.5f + 15 ; rectRight = r + mPaint.getStrokeWidth() * 0.5f ; rectBottom = rectTop + 50 ; } @Override protected void onDraw(Canvas canvas) { // 移动中心canvas.translate(mWidth / 2, mHeight / 2 - 50 ); // 画中心圆 canvas.drawCircle(0, 0 , centerRadius, mCenterPaint); // 是否显示中心圆外的小圆环 if (highlightCenter ||highlightCenterLittle) { int c = mCenterPaint.getColor(); mCenterPaint.setStyle(Paint.Style.STROKE); if (highlightCenter) { mCenterPaint.setAlpha(0xFF); } else if (highlightCenterLittle) { mCenterPaint.setAlpha(0x90 ); } canvas.drawCircle(0, 0 , centerRadius + mCenterPaint.getStrokeWidth(), mCenterPaint); mCenterPaint.setStyle(Paint.Style.FILL); mCenterPaint.setColor(c); } // 画色环 canvas.drawOval(new RectF(-r, - r, r, r), mPaint); // 画黑白渐变块 if (downInCircle) { mRectColors[1] =mCenterPaint.getColor(); } rectShader = new LinearGradient(rectLeft, 0, rectRight, 0, mRectColors, null , Shader.TileMode.MIRROR); mRectPaint.setShader(rectShader); canvas.drawRect(rectLeft, rectTop, rectRight, rectBottom, mRectPaint); float offset = mLinePaint.getStrokeWidth() / 2 ; canvas.drawLine(rectLeft - offset, rectTop - offset * 2 , rectLeft - offset, rectBottom + offset * 2, mLinePaint); // 左 canvas.drawLine(rectLeft - offset * 2, rectTop - offset, rectRight + offset * 2, rectTop - offset, mLinePaint); // 上canvas.drawLine(rectRight + offset, rectTop - offset * 2 , rectRight + offset, rectBottom + offset * 2, mLinePaint); // 右 canvas.drawLine(rectLeft - offset * 2, rectBottom + offset, rectRight + offset * 2, rectBottom + offset, mLinePaint); // 下 super .onDraw(canvas); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX() - mWidth / 2 ; float y = event.getY() - mHeight / 2 + 50 ; boolean inCircle = inColorCircle(x, y, r+ mPaint.getStrokeWidth() / 2, r - mPaint.getStrokeWidth() / 2 ); boolean inCenter =inCenter(x, y, centerRadius); boolean inRect = inRect(x, y); switch (event.getAction()) { caseMotionEvent.ACTION_DOWN: downInCircle = inCircle; downInRect = inRect; highlightCenter= inCenter; case MotionEvent.ACTION_MOVE: if(downInCircle && inCircle) { // down按在渐变色环内, 且move也在渐变色环内 float angle = ( float ) Math.atan2(y, x); float unit = ( float) (angle / (2 * Math.PI)); if (unit < 0 ) { unit += 1 ; } mCenterPaint.setColor(interpCircleColor(mCircleColors, unit)); if(debug) Log.v(TAG, "色环内, 坐标: " + x + "," + y); } else if(downInRect && inRect) { // down在渐变方块内, 且move也在渐变方块内 mCenterPaint.setColor(interpRectColor(mRectColors, x)); } if(debug) Log.v(TAG, "[MOVE] 高亮: " + highlightCenter + "微亮: " + highlightCenterLittle + " 中心: " + inCenter);if((highlightCenter && inCenter) || (highlightCenterLittle && inCenter)) { // 点击中心圆, 当前移动在中心圆 highlightCenter = true ; highlightCenterLittle = false ; } else if(highlightCenter || highlightCenterLittle) { // 点击在中心圆, 当前移出中心圆 highlightCenter = false ; highlightCenterLittle = true ; } else { highlightCenter = false ; highlightCenterLittle = false ; } invalidate(); break ; case MotionEvent.ACTION_UP: if(highlightCenter && inCenter) { // 点击在中心圆, 且当前启动在中心圆 if(mListener != null ) { mListener.colorChanged(mCenterPaint.getColor()); ColorPickerDialog. this .dismiss(); } } if(downInCircle) { downInCircle = false ; } if (downInRect) { downInRect = false ; } if(highlightCenter) { highlightCenter = false ; } if (highlightCenterLittle) { highlightCenterLittle= false ; } invalidate(); break ; } return true ; } @Override protected void onMeasure( intwidthMeasureSpec, int heightMeasureSpec) { super .onMeasure(mWidth, mHeight); } /** * 坐标是否在色环上 * @param x 坐标 * @param y 坐标 * @param outRadius 色环外半径 * @paraminRadius 色环内半径 * @return */ private boolean inColorCircle( float x,float y, float outRadius, float inRadius) { double outCircle = Math.PI * outRadius * outRadius;double inCircle = Math.PI * inRadius * inRadius; double fingerCircle = Math.PI * (x * x + y * y);if(fingerCircle < outCircle && fingerCircle > inCircle) { return true ; } else { return false ; } } /*** 坐标是否在中心圆上 * @param x 坐标 * @param y 坐标 * @param centerRadius 圆半径 * @return */ private boolean inCenter( float x, float y, floatcenterRadius) { double centerCircle = Math.PI * centerRadius * centerRadius; doublefingerCircle = Math.PI * (x * x + y * y); if(fingerCircle < centerCircle) { return true ; } else {return false ; } } /** * 坐标是否在渐变色中 * @param x * @param y * @return */ private boolean inRect( float x, float y) { if( x <= rectRight && x >=rectLeft && y <= rectBottom && y >= rectTop) { return true ; } else { return false ; } } /** * 获取圆环上颜色 * @param colors * @param unit * @return */ private int interpCircleColor( int colors[],float unit) { if (unit <= 0 ) { return colors[0 ]; } if (unit >= 1 ) { return colors[colors.length - 1 ]; } float p = unit * (colors.length - 1 ); int i = ( int )p; p -= i; // now p is just the fractional part [0...1) and i is the index int c0 = colors; int c1 = colors[i+1 ]; int a = ave(Color.alpha(c0), Color.alpha(c1), p); int r = ave(Color.red(c0), Color.red(c1), p); int g = ave(Color.green(c0), Color.green(c1), p); int b = ave(Color.blue(c0), Color.blue(c1), p); return Color.argb(a, r, g, b); }/** * 获取渐变块上颜色 * @param colors * @param x * @return */ private int interpRectColor(int colors[], float x) { int a, r, g, b, c0, c1; float p; if (x < 0 ) { c0 = colors[0 ]; c1 = colors[1 ]; p = (x + rectRight) / rectRight; } else { c0 = colors[1 ]; c1 = colors[2 ]; p = x / rectRight; } a =ave(Color.alpha(c0), Color.alpha(c1), p); r = ave(Color.red(c0), Color.red(c1), p); g =ave(Color.green(c0), Color.green(c1), p); b = ave(Color.blue(c0), Color.blue(c1), p); returnColor.argb(a, r, g, b); } private int ave( int s, int d, float p) { return s + Math.round(p * (d - s)); } } /** * 回调接口 * @author LynK * * Create on 2012-1-6 上午8:21:05 * */ public interface OnColorChangedListener { /** * 回调函数 * @param color 选中的颜色 */ void colorChanged( int color); } public String getTitle() { return title; } public voidsetTitle(String title) { this.title = title; } public int getmInitialColor() { return mInitialColor; }public void setmInitialColor( int mInitialColor) { this.mInitialColor = mInitialColor; } publicOnColorChangedListener getmListener() { return mListener; } public voidsetmListener(OnColorChangedListener mListener) { this.mListener = mListener; } }

本站文章信息来源于网络以及网友投稿,本站只负责对文章进行整理、排版、编辑,是出于传递更多信息之目的,并不意味着赞同其观点或证实其内容的真实性。如果您有什么意见或建议,请联系QQ28-1688-302!

人工智能实验室
相关文章相关文章
  • 英国研发“杀生”机器人 通过生命体获取能量

    英国研发“杀生”机器人 通过生命体获取能量

  • 无人驾驶汽车如何改变城市生活?听听他们怎么说

    无人驾驶汽车如何改变城市生活?听听他们怎么说

  • 未来两年人工智能要怎么走?看这篇就够了

    未来两年人工智能要怎么走?看这篇就够了

  • 韩春雨称已能重复实验结果 近期将有消息公布

    韩春雨称已能重复实验结果 近期将有消息公布

网友点评网友点评
阅读推荐阅读推荐

据国外媒体报道,在过去两年内,聊天机器人(chatbot)、人工智能以及机器学习的研发和采用取得了巨大进展。许多初创公司正利用人工智能和...

霍金 视觉中国 图 英国著名物理学家霍金(Stephen Hawking)再次就人工智能(AI)发声,他认为:对于人类来说,强大AI的出现可能是最美妙的...

文|郑娟娟 今年,人工智能(AI) 60岁了。在AI60岁的时候,笔者想要介绍一下AI100,一个刚刚2岁的研究项目,但它的预设寿命是100年,甚至更长...

AlphaGo与李世石的人机大战,为大众迅速普及了人工智能的概念。 但对谷歌而言,除了下围棋,现在的人工智能进展到哪一步了?未来,人工智能...