Android颜色选择器

废话不多说了,先上效果图

     Android颜色选择器_第1张图片

       中间那个盘可以随手指移动,中心是透明的,通过它读取色盘上的颜色


技术方案:采用组合控件,将颜色选择器封装成一个控件,监听小盘的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]


你可能感兴趣的:(android,控件)