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

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

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

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

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

ColorPickerView:

[java] view plain copy

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

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

[java] view plain copy

  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中关于触摸事件的处理:

[java] view plain copy

  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接口:

并完成对应方法:

[java] view plain copy

  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. }

[java] view plain copy

  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);

[java] view plain copy

  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点击后的颜色设置事件处理:

[java] view plain copy

  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中定义的:

[java] view plain copy

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


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

[java] view plain copy

  1. implements ColorPickerDialog.OnColorChangedListener


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

[java] view plain copy

  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中颜色区域的显示:

[java] view plain copy

  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参数

[java] view plain copy

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


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

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

时间: 2024-10-05 06:34:01

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

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

版权声明:本文为博主原创文章,未经博主允许不得转载. Android 仿PhotoShop调色板应用(三) 主体界面绘制    关于PhotoShop调色板应用的实现我总结了两个最核心的部分:   1. 主体界面不同区域的绘制   2. 颜色选择的生成与交互 这里我讲述一下第一要点,也就是ColorPickerDialog对主体界面的绘制. 首先还是看一下ColorPickerDialog整体显示的效果(见图1)     图1 对应着效果图我画了一张界面结构分析图,相信看了之后会对该界面的组成很

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

版权声明:本文为博主原创文章,未经博主允许不得转载. Android 仿PhotoShop调色板应用(二) 透明度绘制之AlphaPatternDrawable 这里讲一下如何实现PS调色板中的透明度选择条.首先说一下要点: 1. 透明度选择条实际上是基于白色(0xffffffff)和灰色(0xffcbcbcb)之间的颜色区间选取, 由此我们可以实现一个半透明颜色的选取 2.该应用不仅可以做透明度颜色选取,也可以在应用中实现半透明的图像效果 下面看一下代码,主要是基于Drawable的重写: [

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

版权声明:本文为博主原创文章,未经博主允许不得转载. 在前面的系列我已经将Android中颜色渲染的原理及使用做了一个整体上概述. 现在开始根据一个比较复杂的实现进行具体的分析,这就是PhotoShop中的调色板应用 首先还是看一下最终的实现效果:    图1 怎么样,是不是要比API Demos中的ColorPickerDialog要强大得多,而且完全可以媲美PhotoShop中的调色板. 根据此例完全可以得到你想要的颜色,不再仅仅是一个简单的色相上的选取,而是提供一个HSV色彩及透明度的选取

【Android 仿微信通讯录 导航分组列表-上】使用ItemDecoration为RecyclerView打造带悬停头部的分组列表

[Android 仿微信通讯录 导航分组列表-上]使用ItemDecoration为RecyclerView打造带悬停头部的分组列表 一 概述 本文是Android导航分组列表系列上,因时间和篇幅原因分上下,最终上下合璧,完整版效果如下: 上部残卷效果如下:两个ItemDecoration,一个实现悬停头部分组列表功能,一个实现分割线(官方demo) 网上关于实现带悬停分组头部的列表的方法有很多,像我看过有主席的自定义ExpandListView实现的,也看过有人用一个额外的父布局里面套 Rec

Android仿微信下拉列表实现

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 本文要实现微信6.1中点击顶部菜单栏的"+"号按钮时,会弹出一个列表框.这里用的了Activity实现,其实最好的方法可以用ActionBar,不过这货好像只支持3.0以后的版本.本文的接上文Android仿微信底部菜单栏+顶部菜单栏(附源码) 效果: 一.仿微信下拉列表布局pop_dialog.xml <?xml version="1.0" encodi

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 这个类开始接触 OpenGL,探索3D 领域. javax.microedition.khronos.opengles 接口GL10 上级接口:GL 下级接口:GL11 公共接口GL10继承于GL GL10接口包含了Java(TM)程序语言为OpenGL绑定的核心功能.OES_byte_coordin

android仿最新6.2版本微信相册

仿微信相册选择图片,查看大图,写的不太好,希望评论指出不足,谅解,先介绍一下我的基本思路 第一步获取手机上的所有图片路径: Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; ContentResolver contentResolver = getContentResolver(); //获取jpeg和png格式的文件,并且按照时间进行倒序 Cursor cursor = contentResolver.query(uri, null

Android群英传笔记——第四章:ListView使用技巧

Android群英传笔记--第四章:ListView使用技巧 近期也是比較迷茫.可是有一点点还是要坚持的,就是学习了.近期离职了,今天也是继续温习第四章ListView,也拖了事实上也挺久的了,listview可谓是老牌大将了,非常多的应用场景都要使用它,他也是我们用得最多的控件之中的一个了,尽管如今出来了一个RecyclerView,可是ListView的地位一时半会儿还是撼动不了的.这就促使我们更加应该去把他掌握了 一.Listview经常使用优化技巧 我们一步步来把ListView学习好

从零开始学android&lt;FrameLayout帧布局.十四.&gt;

FrameLayout布局(帧布局)就是在屏幕上开辟一个区域以填充所有的组件,但是使用FrameLayout布局会将所有的组件都放在屏幕的左上角,而且所有的组件可以层叠进行显示. <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_