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

 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. OnClose()和 OnDestroy()

    OnClose()和 OnDestroy() 基于对话框的MFC程序,发现每次程序退出时,托盘的小图标不能自动消失,鼠标移上去之后才能消失,比较不爽. 后来发现我删除这个图标的代码是在自己重写的OnC ...

  2. C#Lambda表达式学习日记

    Lambda表达式只是用更简单的方式来写匿名方法,彻底简化了对.NET委托类型的使用. 现在,如果我们要使用泛型 List<> 的 FindAll() 方法,当你从一个集合去提取子集时,可 ...

  3. TCP三次握手和http过程

    pc浏览服务器网页此过程不包括域名查询,只描述TCP与http数据流的变化.一.pc与http服务器进行三次握手来建立连接.1.pc:seq=0 ack=0 syn=1 ack=0 发送给服务器建立同 ...

  4. LA 3904

    一道DP题: 一共有三种砖,1*2,2*1,2*2,然后要你铺满整个n*2的地板,求不重复的铺法数: 方法: 首先计算了不考虑对称的情况,然后计算只考虑对称的情况: 所以结果就是(不考虑对称数+只考虑 ...

  5. 纯CSS实现delay连续动画

    从前css3还没出来的时候,用jquery的delay方法可以串起一个一个独立的动画片段. 那么在不使用jquery的平台上,如何借助css3来完成一些列动作呢? 有高人做了一个动感十足的人物动画: ...

  6. Python 处理EXCEL的CSV文档分列求SUM

    相对于导出EXCEL文件,PYTHON计算更为实时. import csv import sys from optparse import OptionParser def calculate_pro ...

  7. Array.asList()注意

    api: public static <T> List<T> asList(T... a) 返回一个受指定数组支持的固定大小的列表.(对返回列表的更改会“直接写”到数组.)此方 ...

  8. druid配置(转)

    java程序很大一部分要操作数据库,为了提高性能操作数据库的时候,有不得不使用数据库连接池.数据库连接池有很多选择,c3p.dhcp.proxool等,druid作为一名后起之秀,凭借其出色的性能,也 ...

  9. Android listView scroll 恢复滚动位置

    相信大家尝试过许多方法恢复滚动位置,本人也找了许多方法,唯有这个方法好用,下面把代码贴出来 声明两个变量 private int mPosition; private int lvChildTop; ...

  10. View转化为bitmap

    private Bitmap getViewBitmap(View v) { v.clearFocus(); v.setPressed(false); boolean willNotCache = v ...