zoukankan      html  css  js  c++  java
  • Android 仿PhotoShop调色板应用(四) 不同区域颜色选择的颜色生成响应

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


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

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



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

    并完成对应方法:

    1. @Override  
    2. public void onColorChanged(int color) {  
    3.   
    4.     mNewColor.setColor(color);// mNewColor即为右下角实时显示颜色的ColorPickerPanelView  
    5.       
    6.     if (mHexValueEnabled)  
    7.         updateHexValue(color);  
    8.   
    9.     /* 
    10.     if (mListener != null) { 
    11.         mListener.onColorChanged(color); 
    12.     } 
    13.     */  
    14.   
    15. }  
    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.   
    12.       if (alpha.length() == 1) {  
    13.           alpha = "0" + alpha;  
    14.       }  
    15.   
    16.       if (red.length() == 1) {  
    17.           red = "0" + red;  
    18.       }  
    19.   
    20.       if (green.length() == 1) {  
    21.           green = "0" + green;  
    22.       }  
    23.   
    24.       if (blue.length() == 1) {  
    25.           blue = "0" + blue;  
    26.       }  
    27.   
    28.       return "#" + alpha + red + green + blue;  
    29.   }  



    最后看一下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.   
    3. ublic interface OnColorChangedListener {  
    4. 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.         }  
    13.     }  

    调用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 UI开发第三十二篇——Creating a Navigation Drawer
    Asynchronous HTTP Requests in Android Using Volley
    AndroidHttp通信 HTTP Client与HttpURLConnection的区别
    Volley使用详细说明
    网络通信框架Volley使用详细说明
    Google I/O 2013 – Volley: Easy, Fast Networking for Android
    Android UI开发第三十一篇——Android的Holo Theme
    存储过程多值参数报表
    报表如何嵌入到网页并接收参数?
    多选参数可为空报表的实现方法
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/5571868.html
Copyright © 2011-2022 走看看