版权声明:本文为博主原创文章,未经博主允许不得转载。

 Android 仿PhotoShop调色板应用(四) 不同区域颜色选择的颜色生成响应

 上一篇讲过了主体界面的绘制,这里讲解调色板应用中的另外一个核心: 颜色选择及生成.

ColorPcikerView中不同部分的选择和ColorPickerPanelView中颜色显示是怎样响应的呢?这里当然少不了回调函数:

ColorPickerView:

  1. public interface OnColorChangedListener {
  2. public void onColorChanged(int color);
  3. }

然后看一下轨迹球的事件处理:

  1. @Override
  2. public boolean onTrackballEvent(MotionEvent event) {
  3. float x = event.getX();
  4. float y = event.getY();
  5. boolean update = false;//是否需要更新颜色
  6. if(event.getAction() == MotionEvent.ACTION_MOVE){
  7. switch(mLastTouchedPanel){
  8. case PANEL_SAT_VAL://饱和度&亮度选择区域
  9. float sat, val;
  10. sat = mSat + x/50f;
  11. val = mVal - y/50f;
  12. if(sat < 0f){
  13. sat = 0f;
  14. }
  15. else if(sat > 1f){
  16. sat = 1f;
  17. }
  18. if(val < 0f){
  19. val = 0f;
  20. }
  21. else if(val > 1f){
  22. val = 1f;
  23. }
  24. mSat = sat;
  25. mVal = val;
  26. update = true;
  27. break;
  28. case PANEL_HUE://色相选择区域
  29. float hue = mHue - y * 10f;
  30. if(hue < 0f){
  31. hue = 0f;
  32. }
  33. else if(hue > 360f){
  34. hue = 360f;
  35. }
  36. mHue = hue;
  37. update = true;
  38. break;
  39. case PANEL_ALPHA://透明度选择区域
  40. if(!mShowAlphaPanel || mAlphaRect == null){
  41. update = false;
  42. }
  43. else{
  44. int alpha = (int) (mAlpha - x*10);
  45. if(alpha < 0){
  46. alpha = 0;
  47. }
  48. else if(alpha > 0xff){
  49. alpha = 0xff;
  50. }
  51. mAlpha = alpha;
  52. update = true;
  53. }
  54. break;
  55. }
  56. }
  57. if(update){//如果需要更新,调用对用的回调函数并重新绘制
  58. if(mListener != null){//参数需要由HSV格式的float数组转换为ARGB格式的 int 参数
  59. mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal}));
  60. }
  61. invalidate();
  62. return true;
  63. }
  64. return super.onTrackballEvent(event);
  65. }


ColorPickerView中关于触摸事件的处理:

  1. @Override
  2. public boolean onTouchEvent(MotionEvent event) {
  3. boolean update = false;
  4. switch(event.getAction()){
  5. case MotionEvent.ACTION_DOWN:
  6. mStartTouchPoint = new Point((int)event.getX(), (int)event.getY());
  7. update = moveTrackersIfNeeded(event);
  8. break;
  9. case MotionEvent.ACTION_MOVE:
  10. update = moveTrackersIfNeeded(event);
  11. break;
  12. case MotionEvent.ACTION_UP:
  13. mStartTouchPoint = null;
  14. update = moveTrackersIfNeeded(event);
  15. break;
  16. }
  17. if(update){
  18. if(mListener != null){
  19. mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal}));
  20. }
  21. invalidate();
  22. return true;
  23. }
  24. return super.onTouchEvent(event);
  25. }
  26. //判断是否触发事件,更新区域颜色
  27. private boolean moveTrackersIfNeeded(MotionEvent event){
  28. if(mStartTouchPoint == null) return false;
  29. boolean update = false;
  30. //获取触摸点X,Y坐标值
  31. int startX = mStartTouchPoint.x;
  32. int startY = mStartTouchPoint.y;
  33. //判断 X,Y坐标是否在对应的区域内,并做相应的处理
  34. if(mHueRect.contains(startX, startY)){
  35. mLastTouchedPanel = PANEL_HUE;
  36. mHue = pointToHue(event.getY());
  37. update = true;
  38. }
  39. else if(mSatValRect.contains(startX, startY)){
  40. mLastTouchedPanel = PANEL_SAT_VAL;
  41. float[] result = pointToSatVal(event.getX(), event.getY());
  42. mSat = result[0];
  43. mVal = result[1];
  44. update = true;
  45. }
  46. else if(mAlphaRect != null && mAlphaRect.contains(startX, startY)){
  47. mLastTouchedPanel = PANEL_ALPHA;
  48. mAlpha = pointToAlpha((int)event.getX());
  49. update = true;
  50. }
  51. return update;
  52. }

使用时,让ColorPickerDialog实现ColorPickerView.OnColorChangedListener接口:

并完成对应方法:

  1. @Override
  2. public void onColorChanged(int color) {
  3. mNewColor.setColor(color);// mNewColor即为右下角实时显示颜色的ColorPickerPanelView
  4. if (mHexValueEnabled)
  5. updateHexValue(color);
  6. /*
  7. if (mListener != null) {
  8. mListener.onColorChanged(color);
  9. }
  10. */
  11. }
  1. private void updateHexValue(int color) {
  2. if (getAlphaSliderVisible()) {
  3. mHexVal.setText(ColorPickerPreference.convertToARGB(color).toUpperCase(Locale.getDefault()));
  4. } else {
  5. mHexVal.setText(ColorPickerPreference.convertToRGB(color).toUpperCase(Locale.getDefault()));
  6. }
  7. mHexVal.setTextColor(mHexDefaultTextColor);
  1. /** 转化为ARGB格式字符串
  2. * For custom purposes. Not used by ColorPickerPreferrence
  3. * @param color
  4. * @author Unknown
  5. */
  6. public static String convertToARGB(int color) {
  7. String alpha = Integer.toHexString(Color.alpha(color));
  8. String red = Integer.toHexString(Color.red(color));
  9. String green = Integer.toHexString(Color.green(color));
  10. String blue = Integer.toHexString(Color.blue(color));
  11. if (alpha.length() == 1) {
  12. alpha = "0" + alpha;
  13. }
  14. if (red.length() == 1) {
  15. red = "0" + red;
  16. }
  17. if (green.length() == 1) {
  18. green = "0" + green;
  19. }
  20. if (blue.length() == 1) {
  21. blue = "0" + blue;
  22. }
  23. return "#" + alpha + red + green + blue;
  24. }

最后看一下ColorPickerPanelView点击后的颜色设置事件处理:

  1. @Override
  2. public void onClick(View v) {
  3. if (v.getId() == R.id.new_color_panel) {
  4. if (mListener != null) {
  5. mListener.onColorChanged(mNewColor.getColor());
  6. }
  7. }
  8. dismiss();
  9. }

注意一下,这里的OnColorChangedListener是在ColorPickerDialog中定义的:

  1. private OnColorChangedListener mListener;
  2. ublic interface OnColorChangedListener {
  3. public void onColorChanged(int color);


最终的颜色是怎么显示到ColorPickerPreference上呢,其实实现的方法是一样的:

  1. implements ColorPickerDialog.OnColorChangedListener


在ColorPickerPreference中实现对应的回调方法:

  1. @Override
  2. public void onColorChanged(int color) {
  3. if (isPersistent()) {
  4. persistInt(color);
  5. }
  6. mValue = color;
  7. setPreviewColor();
  8. try {
  9. getOnPreferenceChangeListener().onPreferenceChange(this, color);
  10. } catch (NullPointerException e) {
  11. }
  12. }

调用setPreviewColor()改变ColorPickerPreference中颜色区域的显示:

  1. private void setPreviewColor() {
  2. if (mView == null) return;
  3. ImageView iView = new ImageView(getContext());
  4. LinearLayout widgetFrameView = ((LinearLayout)mView.findViewById(android.R.id.widget_frame));
  5. if (widgetFrameView == null) return;
  6. widgetFrameView.setVisibility(View.VISIBLE);
  7. widgetFrameView.setPadding(
  8. widgetFrameView.getPaddingLeft(),
  9. widgetFrameView.getPaddingTop(),
  10. (int)(mDensity * 8),
  11. widgetFrameView.getPaddingBottom()
  12. );
  13. // remove already create preview image
  14. int count = widgetFrameView.getChildCount();
  15. if (count > 0) {
  16. widgetFrameView.removeViews(0, count);
  17. }
  18. widgetFrameView.addView(iView);
  19. widgetFrameView.setMinimumWidth(0);
  20. iView.setBackgroundDrawable(new AlphaPatternDrawable((int)(5 * mDensity)));
  21. iView.setImageBitmap(getPreviewBitmap());
  22. }


最后调用getOnPreferenceChangeListener().onPreferenceChange(this, color);改变颜色设置值

然后在下次打开ColorPickerDialog时,传入上面onColorChanged()回调实现中已经改变的mValue参数

  1. mDialog = new ColorPickerDialog(getContext(), mValue);


至此,PS调色板应用中颜色交互的事件讲解完毕.

相信当分析完PhotoShop调色板应用后,大家会对颜色渲染方面会有一个认识上的提高.

Android 仿PhotoShop调色板应用(四) 不同区域颜色选择的颜色生成响应的更多相关文章

  1. Android 仿PhotoShop调色板应用(三) 主体界面绘制

    版权声明:本文为博主原创文章,未经博主允许不得转载. Android 仿PhotoShop调色板应用(三) 主体界面绘制    关于PhotoShop调色板应用的实现我总结了两个最核心的部分:   1 ...

  2. Android 仿PhotoShop调色板应用(二) 透明度绘制之AlphaPatternDrawable

    版权声明:本文为博主原创文章,未经博主允许不得转载. Android 仿PhotoShop调色板应用(二) 透明度绘制之AlphaPatternDrawable 这里讲一下如何实现PS调色板中的透明度 ...

  3. Android 仿PhotoShop调色板应用(一)概述

    版权声明:本文为博主原创文章,未经博主允许不得转载. 在前面的系列我已经将Android中颜色渲染的原理及使用做了一个整体上概述. 现在开始根据一个比较复杂的实现进行具体的分析,这就是PhotoSho ...

  4. Android仿人人客户端(v5.7.1)——个人主页(三)

    转载请标明出处:http://blog.csdn.net/android_ls/article/details/9405089 声明:仿人人项目,所用所有图片资源都来源于其它Android移动应用,编 ...

  5. Android仿人人客户端(v5.7.1)——新鲜事之完整篇

    转载请标明出处: http://blog.csdn.net/android_ls/article/details/9228083       声明:仿人人项目,所用所有图片资源都来源于其它Androi ...

  6. Android OpenGL ES(十四)gl10方法解析

    Android 支持 OpenGL 列表 1.GL 2.GL 10 3.GL 10 EXT 4.GL 11 5.GL 11 EXT 6.GL 11 ExtensionPack 我们将使用 GL10 这 ...

  7. Android 仿知乎创意广告

    代码地址如下:http://www.demodashi.com/demo/14904.html 一.概述 貌似前段时间刷知乎看到的一种非常有特色的广告展现方式,即在列表页,某一个Item显示背后部分广 ...

  8. Android仿微信图片上传,可以选择多张图片,缩放预览,拍照上传等

    仿照微信,朋友圈分享图片功能 .可以进行图片的多张选择,拍照添加图片,以及进行图片的预览,预览时可以进行缩放,并且可以删除选中状态的图片 .很不错的源码,大家有需要可以下载看看 . 微信 微信 微信 ...

  9. android仿漫画源码、抽奖转盘、Google相册、动画源码等

    Android精选源码 android实现仿今日头条的开源项目 波浪效果,实现流量的动态显示 美妆领域的app, 集成了摄像头取色, 朋友圈, 滤镜等 android仿漫画源码 android一个视差 ...

随机推荐

  1. 浅谈Exchange 2013开发-如何操作邮件的附件

    因为项目中客户有一个的要求,所以这个Exchange前段时间搞的我很是头疼,没接触过这个东西,但是现在看来,纸老虎一个.希望我的经验可以帮助初次接触它的人少走一些弯路! 简单介绍一下:客户要求在自己的 ...

  2. u-boot子目录Makefile分析

    一.概述 u-boot的子目录Makefile是整个Makefile体系的重要组成部分,决定了对应子目录的编译过程. 二.分析 以cpu/arm920t/Makefile为例进行说明 (1)首先,调用 ...

  3. js一些方法的扩展

    //JS扩展方法与C#的扩展方法非常相似,也是可以链式调用的,也是通过对某个类的扩展写法来实现.这个东西非常好用,如果将预先写好的方法放到一个js里面引用的话,那么后面写js将非常有趣. //下面给出 ...

  4. php mysql PDO使用

    <?php $dbh = new PDO('mysql:host=localhost;dbname=access_control', 'root', ''); $dbh->setAttri ...

  5. [Codeforces Round #296 div2 D] Clique Problem 【线段树+DP】

    题目链接:CF - R296 - d2 - D 题目大意 一个特殊的图,一些数轴上的点,每个点有一个坐标 X,有一个权值 W,两点 (i, j) 之间有边当且仅当 |Xi - Xj| >= Wi ...

  6. websphere性能设置和日常维护

    一. 确认磁盘空间是否满足要求1. WebSphere 应用服务器自身代码的占用空间.这个空间一般在1G左右,在不同的系统平台上略有差异. 2. 概要文件所占的空间.WebSphere应用服务器V6. ...

  7. 【Java】java基本知识

    1.int与Integer的区别 int是基本数据类型,Integer是一个引用数据类型. e.g: int num = 100; // 不是对象 Integer i = 100; // 是对象 // ...

  8. server-send event object

    http://jamie-wang.iteye.com/blog/1849193 event -- onmessage, onopen, onerror 不是方法,而是事件 http://school ...

  9. socket.io发送给指定的客户端

    http://www.cnblogs.com/ajccom/archive/2013/07/18/3197809.html http://stackoverflow.com/questions/100 ...

  10. node案例

    http://www.cnblogs.com/wewe/archive/2010/03/19/1685658.html http://www.laonan.net/blog/69/ http://cn ...