废话不多说了,先上效果图
中间那个盘可以随手指移动,中心是透明的,通过它读取色盘上的颜色
技术方案:采用组合控件,将颜色选择器封装成一个控件,监听小盘的onTouch事件
1、组合控件布局
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/rl_root" android:layout_width="wrap_content" android:layout_height="wrap_content" > <ImageView android:id="@+id/iv_color_range" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_margin="30dp" android:src="@drawable/color_range" /> <ImageView android:id="@+id/iv_color_picker" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:background="@drawable/color_picker" android:clickable="true" /> </RelativeLayout>
android:layout_margin="30dp" 是为了使小盘滑动到大盘边缘不被裁剪掉,具体效果,大家可以去掉试试
android:clickable="true" 如果不设这属性,ImageView将滑动不了
2、组合控件代码
/** * 工程名: colorpicker * 文件名: ColorPickerView.java * 包名: com.style.colorpicker * 日期: 2014-3-30上午10:14:15 * Copyright (c) 2014 * */ package com.style.colorpicker; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.drawable.BitmapDrawable; import android.util.AttributeSet; import android.util.FloatMath; import android.util.Log; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.RelativeLayout; /** * 类名: ColorPickerView <br/> * 功能: 颜色选择器. <br/> * 日期: 2014-3-30 上午10:14:15 <br/> * * @author msl * @version */ public class ColorPickerView extends FrameLayout { private ImageView iv_color_range;//颜色选择盘 private ImageView iv_color_picker;//颜色选择器 private RelativeLayout rl_root;//根布局 private int range_radius ;//圆盘半径 private int picker_radius;//颜色选择器半径 private int centreX;//圆盘中心X坐标 private int centreY;//圆盘中心Y坐标 private int picker_centreX;//颜色选择器中心X坐标 private int picker_centreY;//颜色选择器中心Y坐标 private Bitmap bitmap;//颜色选择盘图片 private onColorChangedListener colorChangedListener;//颜色变换监听 public ColorPickerView(Context context) { super(context); } public ColorPickerView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } /** * * init:(初始化). <br/> * @author msl * @param context * @since 1.0 */ private void init(Context context){ View view = LayoutInflater.from(context).inflate(R.layout.color_picker, this); iv_color_range = (ImageView) view.findViewById(R.id.iv_color_range); iv_color_picker = (ImageView) view.findViewById(R.id.iv_color_picker); rl_root = (RelativeLayout)view.findViewById(R.id.rl_root); //选择器触摸监听 iv_color_picker.setOnTouchListener(new OnTouchListener() { int lastX, lastY;//上次触摸坐标 @Override public boolean onTouch(View v, MotionEvent event) { int ea=event.getAction(); if(range_radius==0){//未初始化 range_radius =iv_color_range.getWidth()/2;//圆盘半径 picker_radius = iv_color_picker.getWidth()/2;//选择器半径 centreX =iv_color_range.getRight()-range_radius; centreY =iv_color_range.getBottom()-iv_color_range.getHeight()/2; bitmap =((BitmapDrawable)iv_color_range.getDrawable()).getBitmap();//获取圆盘图片 } switch(ea){ case MotionEvent.ACTION_DOWN://按下 lastX = (int) event.getRawX(); lastY = (int) event.getRawY(); getParent().requestDisallowInterceptTouchEvent(true);//通知父控件勿拦截本控件touch事件 break; case MotionEvent.ACTION_MOVE://拖动 //拖动距离 int dx =(int)event.getRawX() - lastX; int dy =(int)event.getRawY() - lastY; //相对于父控件的新坐标 int left = v.getLeft() + dx; int top = v.getTop() + dy; int right = v.getRight() + dx; int bottom = v.getBottom() + dy; //选择器圆心坐标 picker_centreX = right-picker_radius; picker_centreY = bottom-picker_radius; //选择器圆心与圆盘圆心距离 float diff = FloatMath.sqrt((centreY-picker_centreY)*(centreY-picker_centreY)+(centreX-picker_centreX)* (centreX-picker_centreX))+picker_radius/2;//两个圆心距离+颜色选择器半径 //在边距内,则拖动 if(diff<=range_radius){ v.layout(left, top, right, bottom); int pixel = bitmap.getPixel(picker_centreX-iv_color_range.getLeft(), picker_centreY-iv_color_range.getTop());//获取选择器圆心像素 if(colorChangedListener!=null){//读取颜色 colorChangedListener.colorChanged(Color.red(pixel), Color.blue(pixel), Color.green(pixel)); } Log.d("TAG", "radValue="+Color.red(pixel)+" blueValue="+Color.blue(pixel)+" greenValue"+Color.green(pixel)); lastX = (int) event.getRawX(); lastY = (int) event.getRawY(); } getParent().requestDisallowInterceptTouchEvent(true);//通知父控件勿拦截本控件touch事件 break; default: break; } return false; } }); } public onColorChangedListener getColorChangedListener() { return colorChangedListener; } public void setColorChangedListener(onColorChangedListener colorChangedListener) { this.colorChangedListener = colorChangedListener; } /** * 颜色变换监听接口 */ interface onColorChangedListener{ public void colorChanged(int red,int blue,int green); } }
3、使用
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <com.style.colorpicker.ColorPickerView android:id="@+id/cpv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" /> </RelativeLayout>
demo下载地址:github下载
demo粗糙,尤其是滑到边缘时,体验不好,仅供大家参考。有什么建议和疑问,可以邮件联系:[email protected]