最近做项目需要用到调色板功能,本着不重复造轮子的想法,找到一个比较好的实现方式:Android 仿PhotoShop调色板应用。拿给老大看,老大说要做成RGB效果,不要HSV,因为不需要黑白色。好吧,吐槽下,最后还是要用HSV的颜色,找了几个,实现效果都不是很好,要不就是不能自定义属性,要不就是画出来是环形,不符合要求,干脆自己重写一个。先看下效果:

看到网上有人用了7种颜色的数组画出一个圆,不太明白什么意思,干脆用iOS的方式,设置一个背景圆,然后触摸的时候取色就可以,这样如果颜色不行的话直接再换张图片就行。下面上码:

首先是在values下attrs.xml自定义几个属性:

<?xml version="1.0" encoding="utf-8"?>
<resources><declare-styleable name="color_picker"><!-- 背景圆的半径 --><attr name="circle_radius" format="dimension" /><!-- 可滑动小球的半径 --><attr name="center_radius" format="dimension" /><!-- 可滑动小球的颜色 --><attr name="center_color" format="color" /></declare-styleable></resources>

自定义ColorPickView继承View,主要是背景图和中间圆,然后触摸的时候取位置和触摸位置的颜色。注释写的比较详细,应该都能看懂:

package com.xiaowu.colorpicker;import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;public class ColorPickView extends View {private Context context;private int bigCircle; // 外圈半径private int rudeRadius; // 可移动小球的半径private int centerColor; // 可移动小球的颜色private Bitmap bitmapBack; // 背景图片private Paint mPaint; // 背景画笔private Paint mCenterPaint; // 可移动小球画笔private Point centerPoint;// 中心位置private Point mRockPosition;// 小球当前位置private OnColorChangedListener listener; // 小球移动的监听private int length; // 小球到中心位置的距离public ColorPickView(Context context) {super(context);}public ColorPickView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);this.context = context;init(attrs);}public ColorPickView(Context context, AttributeSet attrs) {super(context, attrs);this.context = context;init(attrs);}public void setOnColorChangedListener(OnColorChangedListener listener) {this.listener = listener;}/*** @describe 初始化操作* @param attrs*/private void init(AttributeSet attrs) {// 获取自定义组件的属性TypedArray types = context.obtainStyledAttributes(attrs,R.styleable.color_picker);try {bigCircle = types.getDimensionPixelOffset(R.styleable.color_picker_circle_radius, 100);rudeRadius = types.getDimensionPixelOffset(R.styleable.color_picker_center_radius, 10);centerColor = types.getColor(R.styleable.color_picker_center_color,Color.WHITE);} finally {types.recycle(); // TypeArray用完需要recycle}// 将背景图片大小设置为属性设置的直径bitmapBack = BitmapFactory.decodeResource(getResources(),R.drawable.piccolor);bitmapBack = Bitmap.createScaledBitmap(bitmapBack, bigCircle * 2,bigCircle * 2, false);// 中心位置坐标centerPoint = new Point(bigCircle, bigCircle);mRockPosition = new Point(centerPoint);// 初始化背景画笔和可移动小球的画笔mPaint = new Paint();mPaint.setAntiAlias(true);mCenterPaint = new Paint();mCenterPaint.setColor(centerColor);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// 画背景图片canvas.drawBitmap(bitmapBack, 0, 0, mPaint);// 画中心小球canvas.drawCircle(mRockPosition.x, mRockPosition.y, rudeRadius,mCenterPaint);}@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN: // 按下length = getLength(event.getX(), event.getY(), centerPoint.x,centerPoint.y);if (length > bigCircle - rudeRadius) {return true;}break;case MotionEvent.ACTION_MOVE: // 移动length = getLength(event.getX(), event.getY(), centerPoint.x,centerPoint.y);if (length <= bigCircle - rudeRadius) {mRockPosition.set((int) event.getX(), (int) event.getY());} else {mRockPosition = getBorderPoint(centerPoint, new Point((int) event.getX(), (int) event.getY()), bigCircle- rudeRadius);}listener.onColorChange(bitmapBack.getPixel(mRockPosition.x,mRockPosition.y));break;case MotionEvent.ACTION_UP:// 抬起break;default:break;}invalidate(); // 更新画布return true;}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// 视图大小设置为直径setMeasuredDimension(bigCircle * 2, bigCircle * 2);}/*** @describe 计算两点之间的位置* @param x1* @param y1* @param x2* @param y2* @return*/public static int getLength(float x1, float y1, float x2, float y2) {return (int) Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));}/*** @describe 当触摸点超出圆的范围的时候,设置小球边缘位置* @param a* @param b* @param cutRadius* @return*/public static Point getBorderPoint(Point a, Point b, int cutRadius) {float radian = getRadian(a, b);return new Point(a.x + (int) (cutRadius * Math.cos(radian)), a.x+ (int) (cutRadius * Math.sin(radian)));}/*** @describe 触摸点与中心点之间直线与水平方向的夹角角度* @param a* @param b* @return*/public static float getRadian(Point a, Point b) {float lenA = b.x - a.x;float lenB = b.y - a.y;float lenC = (float) Math.sqrt(lenA * lenA + lenB * lenB);float ang = (float) Math.acos(lenA / lenC);ang = ang * (b.y < a.y ? -1 : 1);return ang;}// 颜色发生变化的回调接口public interface OnColorChangedListener {void onColorChange(int color);}
}

引用的时候很简单,设置好属性就行:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:colorpicker="http://schemas.android.com/apk/res/com.xiaowu.colorpicker"android:layout_width="match_parent"android:layout_height="match_parent" ><com.xiaowu.colorpicker.ColorPickViewandroid:id="@+id/color_picker_view"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerHorizontal="true"android:gravity="center"colorpicker:center_color="#FFFFFF"colorpicker:center_radius="10dp"colorpicker:circle_radius="150dp" /><TextViewandroid:id="@+id/txt_color"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@+id/color_picker_view"android:layout_centerHorizontal="true"android:layout_marginTop="37dp"android:text="color" /></RelativeLayout>

写个场景类测试下:

package com.xiaowu.colorpicker;import com.xiaowu.colorpicker.ColorPickView.OnColorChangedListener;import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;public class MainActivity extends Activity {private TextView txtColor;private ColorPickView myView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);myView = (ColorPickView) findViewById(R.id.color_picker_view);txtColor = (TextView) findViewById(R.id.txt_color);myView.setOnColorChangedListener(new OnColorChangedListener() {@Overridepublic void onColorChange(int color) {txtColor.setTextColor(color);}});}}

代码挺简单,基本都在这了,想直接下载代码的地址在下面:

http://download.csdn.net/detail/zhaoshuiruoli/7832577

Android自定义圆形调色板,可设置属性相关推荐

  1. Android自定义圆形进度条

    Android自定义圆形进度条 github地址:https://github.com/opq1289/CircleProgressView 效果图: 无动画: 有动画: 整圆: 切割圆: 具体步骤: ...

  2. android自定义弧度按钮,Android 自定义View 绘制六边形设置按钮

    今天逛酷安的时候,发现酷安的设置按钮(截图的右上角),是一个六边形 + 中心圆的图标,所以又是一个自定义View练习对象了.画圆很简单,知道半径即可,而重点就在画出六边形. 酷安截图.png 最终效果 ...

  3. android自定义圆形图像

    这篇博客给大家带来使用xfermode实现圆形图像.先看效果: 这里说下原理,先看下图: 这里src和dst分别表示不同的bitmap,上面的图片有16种类型,分别表示不同情况下的交集,这里我们需要使 ...

  4. Android 自定义圆形文字头像

    因为最近做一个项目,需要用到圆形头像,然后中间显示用户名的第一个字符,记得之前网上有看到该开源库,但是忽然就找不到了,无奈,只能自己写一个控件. 该控件继承ImageView,主要有以下几个属性: 自 ...

  5. Android 自定义圆形图片 CircleImageView

    1.效果预览 1.1.布局中写自定义圆形图片的路径即可 1.2.然后看一看图片效果 1.3.原图是这样的 @mipmap/ic_launcher 2.使用过程 2.1.CircleImageView源 ...

  6. android小球移动代码,Android自定义圆形View实现小球跟随手指移动效果

    本文实例为大家分享了Android实现小球跟随手指移动效果的具体代码,供大家参考,具体内容如下 一. 需求功能 手指在屏幕上滑动,红色的小球始终跟随手指移动. 实现的思路: 1)自定义View,在on ...

  7. Android 自定义圆形图片

    代码注释很多,简单说下思路,然后直接贴代码 1.截取选定图片中间区域(宽等于高的正方形) 2.按照控件大小进行缩放 3.画圆,设置paint.setXfermode(new PorterDuffXfe ...

  8. html5跟随手指的小球,Android自定义圆形View实现小球跟随手指移动效果(详细介绍)...

    一. 需求功能 手指在屏幕上滑动,红色的小球始终跟随手指移动. 实现的思路: 1)自定义View,在onDraw中画圆作为小球: 2)重写自定义View的onTouchEvent方法,记录触屏坐标,用 ...

  9. android自定义圆形进度条,实现动态画圆效果

    自定义圆形进度条效果图如下:应用场景如动态显示分数等. view的自定义属性如下attr.xml <?xml version="1.0" encoding="UTF ...

最新文章

  1. LeetCode 75. Sort Colors--Python解法
  2. C语言 cgi(2)
  3. 什么样的数据适合缓存?
  4. java删除第一个节点_访问单个节点的删除(Java)
  5. 严选前端全栈工程师学习笔记
  6. Spring AOP的一个具体例子
  7. python 多继承的问题
  8. linux 32bit 改为64bit问题
  9. 【转】十八个绝招把你从压力中营救出来
  10. lab4 cache lab
  11. [再次模拟]多项式输出
  12. 交换机入门书籍推荐_网络工程学习方法/路线/专业书籍推荐
  13. 【WPS技能】xlsx表格根据单元格的值改变行背景色
  14. 善于学习——总结经验
  15. 使用echarts-gl 绘制3D地球配置详解
  16. 【iOS开发】页面卡顿监控和优化
  17. 2019儿童节前一天考试感想
  18. SQL SERVER 软件和安装步骤
  19. VM14+CentOS7安装教程
  20. [区块链笔记10] remix部署合约并连接Ganache 前端web3与智能合约交互

热门文章

  1. ./和../以及/之间的区别?终于弄懂,写的很详细!!!
  2. 【大学生软件测试基础】三角形构成问题 - 决策表
  3. VC++ CTime COleDateTime的常用操作和比较
  4. 在虚拟机(centos)配置postgresql数据库(1) - 安装篇
  5. 《WEB开发-HEXO博客搭建》第3章 Hexo博客域名添加
  6. 介绍一款数据库管理软件
  7. spring aop 执行顺序(@Before @Around @After @AfterReturning @AfterThrowing)
  8. 雪花算法中的时间回拨问题解决方案
  9. DECODE函数常用语法
  10. linux atop日志查看,A - atop - 监控Linux系统资源与进程的工具 - 《Linux命令大全搜索工具(旧版)》 - 书栈网 · BookStack...