自定义颜色控件の颜色采集View
来源:互联网 发布:polyfit函数在c语言 编辑:程序博客网 时间:2024/05/16 17:20
自定义的View,效果图如下所示
在自定义View中,除去padding,宽高比例是1:1.1,如果宽度设定好,高度值无效。如果宽度为未确定,按照高度值设定。
对外接口:setOnColorChangedListener()
package com.android.demo;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.LinearGradient;import android.graphics.Paint;import android.graphics.RectF;import android.graphics.Shader;import android.graphics.SweepGradient;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;/** * 取色环控件,中间为当前颜色,触摸外环和矩形框内改变当前颜色,抬起通过接口传递数据。 * 控制高:宽比例为:1.1:1。 * Created by wu on 2015/12/18. */public class ColorPickerView extends View { private final boolean debug = true; private final String TAG = "ColorPicker"; private OnColorChangedListener mListener; 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 int[] mCircleColors;// 渐变色环颜色 private int[] mRectColors;// 渐变方块颜色 private int mInitialColor;//初始颜色 private int mHeight;// View高 private int mWidth;// 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) { this(context, null); } public ColorPickerView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public ColorPickerView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } public void init() { // 渐变色环参数 mCircleColors = new int[]{0xFFFF0000, 0xFFFF00FF, 0xFF0000FF, 0xFF00FFFF, 0xFF00FF00, 0xFFFFFF00, 0xFFFF0000}; Shader s = new SweepGradient(0, 0, mCircleColors, null); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setShader(s); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(70); mInitialColor = 0xFFFF0000; // 中心圆参数 mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mCenterPaint.setColor(mInitialColor); mCenterPaint.setStrokeWidth(5); // 边框参数 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); } @Override protected void onDraw(Canvas canvas) { // 移动中心 int widthTrans=(mWidth-getPaddingLeft()-getPaddingRight())/2+getPaddingLeft(); int heightTrans=(mWidth-getPaddingLeft()-getPaddingRight()) / 2+getPaddingTop(); canvas.translate(widthTrans,heightTrans); // 画中心圆 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) { int widthTrans=(mWidth-getPaddingLeft()-getPaddingRight())/2+getPaddingLeft(); int heightTrans=(mWidth-getPaddingLeft()-getPaddingRight()) / 2+getPaddingTop(); float x = event.getX() - widthTrans; float y = event.getY() - heightTrans; 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()) { case MotionEvent.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()); } }*/ if (inCircle || inRect) { if (mListener != null) { mListener.colorChanged(mCenterPaint.getColor()); } } if (downInCircle) { downInCircle = false; } if (downInRect) { downInRect = false; } if (highlightCenter) { highlightCenter = false; } if (highlightCenterLittle) { highlightCenterLittle = false; } invalidate(); break; } return true; } /** * 坐标是否在色环上 * * @param x 坐标 * @param y 坐标 * @param outRadius 色环外半径 * @param inRadius 色环内半径 * @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, float centerRadius) { double centerCircle = Math.PI * centerRadius * centerRadius; double fingerCircle = 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[i]; 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); return Color.argb(a, r, g, b); } private int ave(int s, int d, float p) { return s + Math.round(p * (d - s)); } /** * 设定宽高比例 * @param widthMeasureSpec * @param heightMeasureSpec */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int width=widthSize-getPaddingLeft()-getPaddingRight(); int height=heightSize-getPaddingTop()-getPaddingBottom(); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); if (widthMode == MeasureSpec.EXACTLY) { height = (int) (width * 1.1f + 0.5f); } else if (heightMode == MeasureSpec.EXACTLY) { width = (int) (height / 1.1f + 0.5f); } widthMeasureSpec = MeasureSpec.makeMeasureSpec(width+getPaddingLeft()+getPaddingRight(), MeasureSpec.EXACTLY); heightMeasureSpec = MeasureSpec.makeMeasureSpec(height+getPaddingTop()+getPaddingBottom(), MeasureSpec.EXACTLY); setMeasuredDimension(widthMeasureSpec, heightMeasureSpec); } /** * 重新设定圆环半径、中心圆半径以及矩形位置 * @param w * @param h * @param oldw * @param oldh */ @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); this.mHeight = h; this.mWidth = w; int width=mWidth-getPaddingLeft()-getPaddingRight(); int height=mHeight-getPaddingTop()-getPaddingBottom(); mPaint.setStrokeWidth(width/2*0.8f*0.2f);//外圆环的宽度根据设定的宽高进行调整 r = width / 2 * 0.8f - mPaint.getStrokeWidth() * 0.5f; rectLeft = -r - mPaint.getStrokeWidth() * 0.5f; rectRight = r + mPaint.getStrokeWidth() * 0.5f; rectTop = width / 2 - mLinePaint.getStrokeMiter() * 0.5f-0.05f*width; rectBottom = height - width / 2 - mLinePaint.getStrokeMiter()-0.05f*width; centerRadius = (r - mPaint.getStrokeWidth() / 2) * 0.5f; invalidate(); } /** * 设定中心色 * @param mInitialColor */ public void setInitialColor(int mInitialColor) { mCenterPaint.setColor(mInitialColor); } /** * 设定回调接口 * @param listener */ public void setOnColorChangedListener(OnColorChangedListener listener) { mListener = listener; } /** * 回调接口 */ public interface OnColorChangedListener { /** * 回调函数 * * @param color 选中的颜色 */ void colorChanged(int color); }}
0 0
- 自定义颜色控件の颜色采集View
- 自定义View--颜色选择器
- Android自定义View之七色环颜色采集器: 续我未完的大学梦 !
- 自定义view简单的视图控件,控制view的背景颜色
- 自定义View(自定义标题+颜色选择器)
- Android自定义控件提供颜色属性动态改变控件颜色
- 安卓自定义View基础-颜色
- 仿微信Tab颜色渐变自定义View
- Android程序设计:自定义View简单颜色选择器
- 安卓自定义View基础:颜色
- 学习转载系列-《自定义View基础-颜色》
- 安卓自定义View基础-颜色
- 安卓自定义View基础-颜色
- 安卓自定义View基础-颜色
- Android自定义View(三)_颜色
- Android自定义View基础(三)-颜色
- 自定义View之颜色渐变折线图
- android 自定义View--圆环颜色选择器
- 智能家居网络系统设计(二)
- 怎样使用TabPageIndicator 怎样依赖第三方框架
- CTE(CustomTerrainEditor) 自定义地形编辑器(已上传视频, 并更新版本到CTE1.3)
- CTE(Custom Terrain Editor)使用说明
- Win7 Touch API说明
- 自定义颜色控件の颜色采集View
- Unity水效果
- CTE 2.0 更新内容预览(重写所有功能,并且开放源码)(即将发布)
- CTE 2.0 已发布
- java.lang.LinkageError: JAXB 2.0 API is being loaded from the bootstrap classloader, but this RI(***
- utf8编码原理与发展历程
- linux ssh设置
- 【资源】最新Android SDK_API_开发包_离线包_下载
- 今天开始进驻CSDN博客,记录自己unity3d学习的每一步。