zoukankan      html  css  js  c++  java
  • Android 颜色选择器

    实列图:

    源码:

    ColorPickerView.java

    package com.px.color;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Bitmap.Config;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.ComposeShader;
    import android.graphics.LinearGradient;
    import android.graphics.Paint;
    import android.graphics.PointF;
    import android.graphics.PorterDuff;
    import android.graphics.Rect;
    import android.graphics.Shader;
    import android.graphics.Shader.TileMode;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.View;
    
    public class ColorPickerView extends View {
    
    	private Context mContext;
    	
    	private Paint mRightPaint;
    	private int mHeight;
    	private int mWidth;
    	private int[] mRightColors;
    	private int RIGHT_WIDTH;
    	private int LEFT_WIDTH;
    	
    	private Bitmap mLeftBitmap;
    	private Bitmap mLeftBitmap2;
    	private Bitmap mRightBitmap;
    	private Bitmap mRightBitmap2;
    	
    	private Paint mBitmapPaint;
    	
    	private final int SPLIT_WIDTH = 24;
    	
    	private boolean downInLeft = false;
    	private boolean downInRight = false;
    	
    	private PointF mLeftSelectPoint; 
    	private PointF mRightSelectPoint;
    	
    	private OnColorChangedListener mChangedListener;
    	
    	private boolean mLeftMove = false;
    	private boolean mRightMove = false;
    	
    	private float mLeftBitmapRadius;
    	
    	private Bitmap mGradualChangeBitmap;
    	
    	private float mRightBitmapHalfHeight;
    	private float mRightBitmapQuarterWidth;
    	
    	private int mCallBackColor = Integer.MAX_VALUE;
    	
    	public ColorPickerView(Context context) {
    		this(context, null);
    	}
    	
    	public ColorPickerView(Context context, AttributeSet attrs) {
    		super(context, attrs);
    		mContext = context;
    		init();
    	}
    
    	public void setOnColorChangedListenner(OnColorChangedListener listener) {
    		mChangedListener = listener;
    	}
    	
    	private void init() {
    		mRightPaint = new Paint(); 
    		mRightPaint.setStyle(Paint.Style.FILL);
    		mRightPaint.setStrokeWidth(1);
    		
    		mRightColors = new int[3];
    		mRightColors[0] = Color.WHITE;
    		mRightColors[2] = Color.BLACK;
    		
    		mBitmapPaint = new Paint();
    		
    		mLeftBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.reading__color_view__button);
    		mLeftBitmap2 = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.reading__color_view__button_press);
    		mLeftBitmapRadius = mLeftBitmap.getWidth() / 2;
    		mLeftSelectPoint = new PointF(SPLIT_WIDTH, SPLIT_WIDTH);
    		
    		mRightBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.reading__color_view__saturation);
    		mRightBitmap2 = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.reading__color_view__saturation_press);
    		mRightSelectPoint = new PointF(SPLIT_WIDTH, SPLIT_WIDTH);
    		mRightBitmapHalfHeight = mRightBitmap.getHeight() / 2;
    		mRightBitmapQuarterWidth = mRightBitmap.getWidth() / 4;
    		RIGHT_WIDTH = mRightBitmap.getWidth() / 2;
    	}
    	
    	@Override
    	protected void onDraw(Canvas canvas) {
    		// 左边
    		canvas.drawBitmap(getGradual() , null , new Rect(SPLIT_WIDTH, SPLIT_WIDTH, LEFT_WIDTH + SPLIT_WIDTH, mHeight - SPLIT_WIDTH), mBitmapPaint);
    		
    		// 右边
    		mRightColors[1] = mRightPaint.getColor();
    		Shader rightShader = new LinearGradient(mWidth - SPLIT_WIDTH - RIGHT_WIDTH / 2, SPLIT_WIDTH, mWidth - SPLIT_WIDTH - RIGHT_WIDTH / 2, mHeight - SPLIT_WIDTH, mRightColors, null, Shader.TileMode.MIRROR);  
    		mRightPaint.setShader(rightShader);  
    		canvas.drawRect(new Rect(mWidth - SPLIT_WIDTH - RIGHT_WIDTH, SPLIT_WIDTH, mWidth - SPLIT_WIDTH, mHeight-SPLIT_WIDTH), mRightPaint);
    
    		// 两个图标
    		if (mLeftMove) {
    			canvas.drawBitmap(mLeftBitmap, mLeftSelectPoint.x - mLeftBitmapRadius, mLeftSelectPoint.y - mLeftBitmapRadius, mBitmapPaint);
    		} else {
    			canvas.drawBitmap(mLeftBitmap2, mLeftSelectPoint.x - mLeftBitmapRadius, mLeftSelectPoint.y - mLeftBitmapRadius, mBitmapPaint);
    		}
    		
    		if (mRightMove) {
    			canvas.drawBitmap(mRightBitmap, mWidth - SPLIT_WIDTH - RIGHT_WIDTH - mRightBitmapQuarterWidth, mRightSelectPoint.y - mRightBitmapHalfHeight, mBitmapPaint);
    		} else {
    			canvas.drawBitmap(mRightBitmap2, mWidth - SPLIT_WIDTH - RIGHT_WIDTH - mRightBitmapQuarterWidth, mRightSelectPoint.y - mRightBitmapHalfHeight, mBitmapPaint);
    		}
    	}
    	
    	@Override
    	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    		int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    		int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    		int width = MeasureSpec.getSize(widthMeasureSpec);
    		int height = MeasureSpec.getSize(heightMeasureSpec);
    		if (widthMode == MeasureSpec.EXACTLY) {
    			mWidth = width;
    		} else {
    			mWidth = 480;
    		}
    		if (heightMode == MeasureSpec.EXACTLY) {
    			mHeight = height;
    		} else {
    			mHeight = 350;
    		}
    		LEFT_WIDTH = mWidth - SPLIT_WIDTH * 3 - RIGHT_WIDTH;
    		setMeasuredDimension(mWidth, mHeight);
    	}
    	
    	@Override
    	public boolean onTouchEvent(MotionEvent event) {
    		float x = event.getX();
    		float y = event.getY();
    		switch (event.getAction()) {
    		case MotionEvent.ACTION_DOWN:
    		case MotionEvent.ACTION_MOVE:
    			downInLeft = inLeftPanel(x, y);
    			downInRight = inRightPanel(x, y);
    			if (downInLeft) {
    				mLeftMove = true;
    				proofLeft(x, y);
    				mRightPaint.setColor(getLeftColor(mLeftSelectPoint.x-SPLIT_WIDTH, mLeftSelectPoint.y-SPLIT_WIDTH));
    			} else if (downInRight) {
    				mRightMove = true;
    				proofRight(x, y);
    			}
    			
    			invalidate();
    			int rightColor = getRightColor(mRightSelectPoint.y - SPLIT_WIDTH);
    			if (mCallBackColor == Integer.MAX_VALUE || mCallBackColor != rightColor) {
    				mCallBackColor = rightColor;
    			} else {
    				break;
    			}
    			if (mChangedListener != null) {
    				mChangedListener.onColorChanged(mCallBackColor, 
    						mRightPaint.getColor(),
    						(mRightSelectPoint.y - SPLIT_WIDTH) / (mHeight - 2 * SPLIT_WIDTH));
    			}
    			break;
    		case MotionEvent.ACTION_UP:
    			if (downInLeft) {
    				downInLeft = false;
    			} else if (downInRight) {
    				downInRight = false;
    			}
    			mLeftMove = false;
    			mRightMove = false;
    			invalidate();
    			if (mChangedListener != null) {
    				mChangedListener.onColorChanged(getRightColor(mRightSelectPoint.y - SPLIT_WIDTH), 
    						mRightPaint.getColor(),
    						(mRightSelectPoint.y - SPLIT_WIDTH) / (mHeight - 2 * SPLIT_WIDTH));
    			}
    		}
    		return true;
    	}
    	
    	@Override
    	protected void onDetachedFromWindow() {
    		if (mGradualChangeBitmap != null && mGradualChangeBitmap.isRecycled() == false) {
    			mGradualChangeBitmap.recycle();
    		}
    		if (mLeftBitmap != null && mLeftBitmap.isRecycled() == false) {
    			mLeftBitmap.recycle();
    		}
    		if (mLeftBitmap2 != null && mLeftBitmap2.isRecycled() == false) {
    			mLeftBitmap2.recycle();
    		}
    		if (mRightBitmap != null && mRightBitmap.isRecycled() == false) {
    			mRightBitmap.recycle();
    		}
    		if (mRightBitmap2 != null && mRightBitmap2.isRecycled() == false) {
    			mRightBitmap2.recycle();
    		}
    		super.onDetachedFromWindow();
    	}
    	
    	private Bitmap getGradual() {
    		if (mGradualChangeBitmap == null) {
    			Paint leftPaint = new Paint();
    			leftPaint.setStrokeWidth(1);
    			mGradualChangeBitmap = Bitmap.createBitmap(LEFT_WIDTH, mHeight - 2 * SPLIT_WIDTH, Config.RGB_565);
    			Canvas canvas = new Canvas(mGradualChangeBitmap);
    			int bitmapWidth = mGradualChangeBitmap.getWidth();
    			LEFT_WIDTH = bitmapWidth;
    			int bitmapHeight = mGradualChangeBitmap.getHeight();
    			int[] leftColors = new int[] {Color.RED, Color.YELLOW, Color.GREEN, Color.CYAN, Color.BLUE, Color.MAGENTA};
    			Shader leftShader = new LinearGradient(0, bitmapHeight / 2, bitmapWidth, bitmapHeight / 2, leftColors, null, TileMode.REPEAT);
    			LinearGradient shadowShader = new LinearGradient(bitmapWidth / 2, 0, bitmapWidth / 2, bitmapHeight,
    					Color.WHITE, Color.BLACK, Shader.TileMode.CLAMP);
    			ComposeShader shader = new ComposeShader(leftShader, shadowShader, PorterDuff.Mode.SCREEN);
    			leftPaint.setShader(shader);
    			canvas.drawRect(0, 0, bitmapWidth, bitmapHeight, leftPaint);
    		}
    		return mGradualChangeBitmap;
    	}
    	
    	private boolean inLeftPanel(float x, float y) {
    		if ( 0 < x && x < SPLIT_WIDTH + LEFT_WIDTH + SPLIT_WIDTH / 2 && 0 < y && y < mWidth) {
    			return true;
    		} else {
    			return false;
    		}
    	}
    	
    	private boolean inRightPanel(float x, float y) {
    		if (mWidth - SPLIT_WIDTH - RIGHT_WIDTH - SPLIT_WIDTH / 2 < x && x < mWidth && 0 < y && y < mHeight) {
    			return true;
    		} else {
    			return false;
    		}
    	}
    	
    	// 校正xy
    	private void proofLeft(float x, float y) {
    		if (x < SPLIT_WIDTH) {
    			mLeftSelectPoint.x = SPLIT_WIDTH;
    		} else if (x > (SPLIT_WIDTH + LEFT_WIDTH)) {
    			mLeftSelectPoint.x = SPLIT_WIDTH + LEFT_WIDTH;
    		} else {
    			mLeftSelectPoint.x = x;
    		}
    		if (y < SPLIT_WIDTH) {
    			mLeftSelectPoint.y = SPLIT_WIDTH;
    		} else if (y > (mHeight - SPLIT_WIDTH)) {
    			mLeftSelectPoint.y = mHeight - SPLIT_WIDTH;
    		} else {
    			mLeftSelectPoint.y = y;
    		}
    	}
    	
    	private void proofRight(float x, float y) {
    		if (x < SPLIT_WIDTH) {
    			mRightSelectPoint.x = SPLIT_WIDTH;
    		} else if (x > (SPLIT_WIDTH + LEFT_WIDTH)) {
    			mRightSelectPoint.x = SPLIT_WIDTH + LEFT_WIDTH;
    		} else {
    			mRightSelectPoint.x = x;
    		}
    		if (y < SPLIT_WIDTH) {
    			mRightSelectPoint.y = SPLIT_WIDTH;
    		} else if (y > (mHeight - SPLIT_WIDTH)) {
    			mRightSelectPoint.y = mHeight - SPLIT_WIDTH;
    		} else {
    			mRightSelectPoint.y = y;
    		}
    	}
    	
    	private int getLeftColor(float x, float y) {
    		Bitmap temp = getGradual();
    		// 为了防止越界
    		int intX = (int) x;
    		int intY = (int) y;
    		if (intX >= temp.getWidth()) {
    			intX = temp.getWidth() - 1;
    		}
    		if (intY >= temp.getHeight()) {
    			intY = temp.getHeight() - 1;
    		}
            return temp.getPixel(intX, intY);
    	}
    	
    	private int getRightColor(float y) {
    		int a, r, g, b, so, dst;  
    		float p;  
    		
    		float rightHalfHeight = (mHeight - (float)SPLIT_WIDTH * 2) / 2;
    		if (y < rightHalfHeight) {
    			so = mRightColors[0];   
    			dst = mRightColors[1];
    			p =  y / rightHalfHeight;
    		} else {
    			so = mRightColors[1];
    			dst = mRightColors[2];
    			p = (y - rightHalfHeight) / rightHalfHeight;
    		}
      
            a = ave(Color.alpha(so), Color.alpha(dst), p);  
            r = ave(Color.red(so), Color.red(dst), p);  
            g = ave(Color.green(so), Color.green(dst), p);  
            b = ave(Color.blue(so), Color.blue(dst), p);  
            return Color.argb(a, r, g, b);
    	} 
    	
    	private int ave(int s, int d, float p) {
    		return s + Math.round(p * (d - s));
    	}
    	
    	// ### 内部类 ###
    	public interface OnColorChangedListener {
    		void onColorChanged(int color, int originalColor, float saturation);
    	}
    }
    

      

    测试代码:

    ColorPickerActivity.java

    package com.px.color;
    
    import com.px.color.ColorPickerView.OnColorChangedListener;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.util.Log;
    import android.widget.TextView;
    
    public class ColorPickerActivity extends Activity{
        /** Called when the activity is first created. */
    	
    	TextView tv = null;
    	ColorPickerView cpv = null;
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            
            cpv = (ColorPickerView)findViewById(R.id.colorpicker);
            cpv.setOnColorChangedListenner(colorChangedListener);
            
            tv = (TextView)findViewById(R.id.tv);
        }
    
        OnColorChangedListener colorChangedListener = new  OnColorChangedListener(){
    
    		@Override
    		public void onColorChanged(int color, int originalColor,
    				float saturation) {
    			Log.v("ColorPickerActivity", "color = " + color + ", " + "originalColor = " + originalColor);
    			tv.setBackgroundColor(color);
    		}
        };
    }
    

      

  • 相关阅读:
    12-2 mysql 查询
    12-1 mysql的增删改减
    12-1 上午mysql 基本语句
    [题解] [FJOI2016] 建筑师
    [题解] [CF932E] TeamWork
    [题解] [Codechef] CNTDSETS
    [题解] [清华集训 2017] 榕树之心
    [题解] [AGC013D] Piling Up
    [题解] [CQOI2011] 放棋子
    [题解] [ZJOI2017] 仙人掌
  • 原文地址:https://www.cnblogs.com/DswCnblog/p/2741274.html
Copyright © 2011-2022 走看看