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

 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. php中遇到include_path='.;C:\php5\pear'的错误

    所有面页,包括空白的都会报类似下面的错误. Warning: Unknown: failed to open stream: No such file or directory in Unknown  ...

  2. Python 手册——开胃菜

    如果你写过大规模的Shell脚本,应该会有过这样的体会:你还非常想再加一些别的功能进去,但它已经太大. 太慢.太复杂了:或者这个功能需要调用一个系统函数,或者它只适合通过C来调用……通常这些问题还不足 ...

  3. Django设置TIME_ZONE和LANGUAGE_CODE为中国区域

    Django默认的timezone是 TIME_ZONE = 'America/Chicago' LANGUAGE_CODE = 'en-us' 设置为中国区域: TIME_ZONE = 'Asia/ ...

  4. MySQL创建用户、授权等

    用于MySQL5.6命令行执行成功: create database wp_people; create user wp_people@'localhost' identified by 'yrwb' ...

  5. java项目创建和部署

    http://www.cnblogs.com/nexiyi/archive/2012/12/28/2837560.html http://dead-knight.iteye.com/blog/1841 ...

  6. seajs 和spm的使用简介

    说实话, 前端开发是一个令人头痛的事情. nodejs出现了很久了, 一直不是很习惯用nodejs, 当初刚出来的时候, 就下载了express, 想搭建个网站, 结果不是我的菜, 愣是用的不习惯,也 ...

  7. 投稿前必备的cover letter

  8. AWK 简明教程

    AWK 简明教程 转自:http://coolshell.cn/articles/9070.html 有一些网友看了前两天的<Linux下应该知道的技巧>希望我能教教他们用awk和sed, ...

  9. 开源网络备份软件 bacula 的安装、配置和运行

    安装bacula 1 bacula的几种网络备份拓扑 前面文章介绍了bacula有5个组成部分,在实际的应用中,没有必要将5个部分分别放在不同的服务器上,它们之间的某些部分是可以合并的,常见的bacu ...

  10. C#处理四舍五入的问题

    在处理一些数据时,我们希望能用“四舍五入”法实现,但是C#采用的是“四舍六入五成双”的方法,如下面的例子,就是用“四舍六入五成双”得到的结果: double d1 = Math.Round(1.25, ...