Photoshop入门学习之Android 仿PhotoShop调色板应用(三) 主体界面绘制
小标 2018-10-19 来源 : 阅读 1189 评论 0

摘要:本文主要向大家介绍了Photoshop入门学习之Android 仿PhotoShop调色板应用(三) 主体界面绘制,通过具体的内容向大家展现,希望对大家Photoshop入门学习有所帮助。

本文主要向大家介绍了Photoshop入门学习之Android 仿PhotoShop调色板应用(三) 主体界面绘制,通过具体的内容向大家展现,希望对大家Photoshop入门学习有所帮助。

<

关于PhotoShop调色板应用的实现我总结了两个最核心的部分:
  1. 主体界面不同区域的绘制
  2. 颜色选择的生成与交互
 这里我讲述一下第一要点,也就是ColorPickerDialog对主体界面的绘制.
   首先还是看一下ColorPickerDialog整体显示的效果(见图1)
                                          图1
 
对应着效果图我画了一张界面结构分析图,相信看了之后会对该界面的组成很快能够掌握:(见图2)
  图2
一. 界面组成
   可以看到整个显示的部分即为ColorPickerDialog. 这个Dialog根据组件的构成及功能实现上可以分为两大部分:
  1. 红色边框区域  由ColorPickerView绘制而成. 主要作为颜色区域的选择,此区域又划分为三个部分:
      (1)  Saturation Area 饱和度选择区域
      (2)  Hue Area 色相选择区域
      (3)  Alpha Area 透明度选择区域  绘制此区域借助了上一篇讲到的AlphaPatternDrawable类
2. 蓝色边框区域 由ColorPickerPanelView绘制. 左边的部分作为初始颜色显示 右边的部分做颜色选择的实时显示区域,点击后可将颜色设置为默认值
 
该Dialog的布局文件dialog_color_picker.xml:


[java] view plain copy


<?xml version="1.0" encoding="utf-8"?>  
  
<LinearLayout xmlns:android="//schemas.android.com/apk/res/android"  
    android:layout_width="wrap_content"  
    android:layout_height="wrap_content"  
    android:orientation="vertical"  
    android:paddingLeft="5dp"  
    android:paddingRight="5dp" >  
  
    <net.margaritov.preference.colorpicker.ColorPickerView  
        android:id="@+id/color_picker_view"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:layerType="software"  
        android:tag="portrait" />  
  
    <LinearLayout  
        android:id="@+id/text_hex_wrapper"  
        android:layout_width="fill_parent"  
        android:layout_height="wrap_content"  
        android:layout_marginBottom="5dp"  
        android:layout_marginLeft="6dp"  
        android:layout_marginRight="6dp" >  
  
        <TextView  
            android:layout_width="wrap_content"  
            android:layout_height="wrap_content"  
            android:gravity="left"  
            android:text="@string/press_color_to_apply"  
            android:textAppearance="?android:attr/textAppearanceSmall" />  
  
        <EditText  
            android:id="@+id/hex_val"  
            android:layout_width="0dp"  
            android:layout_height="wrap_content"  
            android:layout_weight="1"  
            android:hint="HEX"  
            android:imeOptions="actionDone"  
            android:maxLength="7"  
            android:singleLine="true"  
            android:inputType="textCapCharacters"  
            android:visibility="gone" >  
        </EditText>  
    </LinearLayout>  
  
    <LinearLayout  
        android:layout_width="wrap_content"  
        android:layout_height="40dp"  
        android:layout_marginBottom="10dp"  
        android:orientation="horizontal" >  
  
        <net.margaritov.preference.colorpicker.ColorPickerPanelView  
            android:id="@+id/old_color_panel"  
            android:layout_width="0px"  
            android:layout_height="fill_parent"  
            android:layout_weight="0.5" />  
  
        <TextView  
            android:layout_width="wrap_content"  
            android:layout_height="fill_parent"  
            android:layout_marginLeft="10dp"  
            android:layout_marginRight="10dp"  
            android:gravity="center"  
            android:text="→"  
            android:textSize="20sp" />  
  
        <net.margaritov.preference.colorpicker.ColorPickerPanelView  
            android:id="@+id/new_color_panel"  
            android:layout_width="0px"  
            android:layout_height="wrap_content"  
            android:layout_weight="0.5" />  
    </LinearLayout>  
  
</LinearLayout>  


二. 不同区域的绘制实现:
  1.     Saturation Area 饱和度选择区域
这里用到了组合渲染(ComposeShader)的方式.
 (1)使用了两个线性渲染器:一个作为亮度的显示渲染,一个作为饱和度的显示渲染,    因为我们可以看到颜色渐变和亮度渐变的综合显示效果
      此区域完成了HSV(也叫HSB)色彩空间之Saturation(饱和度)及value(色调)/brightness(明度)的综合显示
(2) 选择圆环绘制:  分为了内外两个圆环分别绘制. 黑色内圆及灰色外圆
      具体实现请看以下代码
 


[java] view plain copy



/** 
     * 绘制饱和度选择区域 
     * @param canvas 
     */  
    private void drawSatValPanel(Canvas canvas){  
  
        final RectF rect = mSatValRect;  
  
        if(BORDER_WIDTH_PX > 0){  
            mBorderPaint.setColor(mBorderColor);  
            canvas.drawRect(mDrawingRect.left, mDrawingRect.top, rect.right + BORDER_WIDTH_PX, rect.bottom + BORDER_WIDTH_PX, mBorderPaint);  
        }  
        //明度线性渲染器  
        if (mValShader == null) {  
            mValShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom,  
                    0xffffffff, 0xff000000, TileMode.CLAMP);  
        }  
        //HSV转化为RGB  
        int rgb = Color.HSVToColor(new float[]{mHue,1f,1f});  
        //饱和线性渲染器  
        mSatShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top,  
                0xffffffff, rgb, TileMode.CLAMP);  
        //组合渲染 = 明度线性渲染器 + 饱和线性渲染器  
        ComposeShader mShader = new ComposeShader(mValShader, mSatShader, PorterDuff.Mode.MULTIPLY);  
        mSatValPaint.setShader(mShader);  
  
        canvas.drawRect(rect, mSatValPaint);  
        //初始化选择圆块的位置  
        Point p = satValToPoint(mSat, mVal);  
        //绘制黑色内圆  
        mSatValTrackerPaint.setColor(0xff000000);  
        canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS - 1f * mDensity, mSatValTrackerPaint);  
        //绘制外圆  
        mSatValTrackerPaint.setColor(0xffdddddd);  
        canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS, mSatValTrackerPaint);  
  
    }  



2.Hue Area 色相选择区域
   (1) 颜色渲染部分仍为竖直方向的线性渐变.这里可以看一下对应颜色数组的生成:


[java] view plain copy



private int[] buildHueColorArray(){  
  
        int[] hue = new int[361];  
  
        int count = 0;  
        for(int i = hue.length -1; i >= 0; i--, count++){  
            hue[count] = Color.HSVToColor(new float[]{i, 1f, 1f});  
        }  
  
        return hue;  
    }  



这里使用了一个大小为361的int数组, 根据当前位置生成不同的 hsv颜色数组
通过Color.HSVToColor,将HSV转换为ARGB的形式,因为在线性渐变渲染中,我们不能直接使用HSV色彩,而是需要使用ARGB制式的颜色.
因此我们看到了一个数值方向的一个多彩变换效果        
(2) 绘制矩形颜色选择条区域
 


[java] view plain copy



/** 
     * 绘制右侧色相选择区域 
     * @param canvas 
     */  
    private void drawHuePanel(Canvas canvas){  
  
        final RectF rect = mHueRect;  
  
        if(BORDER_WIDTH_PX > 0){  
            mBorderPaint.setColor(mBorderColor);  
            canvas.drawRect(rect.left - BORDER_WIDTH_PX,  
                    rect.top - BORDER_WIDTH_PX,  
                    rect.right + BORDER_WIDTH_PX,  
                    rect.bottom + BORDER_WIDTH_PX,  
                    mBorderPaint);  
        }  
        //初始化色相线性渲染器  
        if (mHueShader == null) {  
            mHueShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom, buildHueColorArray(), null, TileMode.CLAMP);  
            mHuePaint.setShader(mHueShader);  
        }  
  
        canvas.drawRect(rect, mHuePaint);  
  
        float rectHeight = 4 * mDensity / 2;  
        //初始化色相选择器选择条位置  
        Point p = hueToPoint(mHue);  
  
        RectF r = new RectF();  
        r.left = rect.left - RECTANGLE_TRACKER_OFFSET;  
        r.right = rect.right + RECTANGLE_TRACKER_OFFSET;  
        r.top = p.y - rectHeight;  
        r.bottom = p.y + rectHeight;  
  
        //绘制选择条  
        canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);  
  
    }  



3. Alpha Area 透明度选择区域
  这里主要借助于AlphaPatternDrawable进行绘制,见上一篇博客:
 Android 仿PhotoShop调色板应用(二) 透明度绘制之AlphaPatternDrawable
具体请见注释,渲染部分和Hue Area类似


[java] view plain copy



/** 
     * 绘制底部透明度选择区域 
     * @param canvas 
     */  
    private void drawAlphaPanel(Canvas canvas){  
  
        if(!mShowAlphaPanel || mAlphaRect == null || mAlphaPattern == null) return;  
  
        final RectF rect = mAlphaRect;  
  
        if(BORDER_WIDTH_PX > 0){  
            mBorderPaint.setColor(mBorderColor);  
            canvas.drawRect(rect.left - BORDER_WIDTH_PX,  
                    rect.top - BORDER_WIDTH_PX,  
                    rect.right + BORDER_WIDTH_PX,  
                    rect.bottom + BORDER_WIDTH_PX,  
                    mBorderPaint);  
        }  
  
          
        mAlphaPattern.draw(canvas);  
          
        float[] hsv = new float[]{mHue,mSat,mVal};//hsv数组  
        int color = Color.HSVToColor(hsv);  
        int acolor = Color.HSVToColor(0, hsv);  
        //初始化透明度线性渲染器  
        mAlphaShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top,  
                color, acolor, TileMode.CLAMP);  
  
          
        mAlphaPaint.setShader(mAlphaShader);  
  
        canvas.drawRect(rect, mAlphaPaint);  
  
        if(mAlphaSliderText != null && mAlphaSliderText!= ""){  
            canvas.drawText(mAlphaSliderText, rect.centerX(), rect.centerY() + 4 * mDensity, mAlphaTextPaint);  
        }  
  
        float rectWidth = 4 * mDensity / 2;  
        //初始化透明度选择器选择条位置  
        Point p = alphaToPoint(mAlpha);  
  
        RectF r = new RectF();  
        r.left = p.x - rectWidth;  
        r.right = p.x + rectWidth;  
        r.top = rect.top - RECTANGLE_TRACKER_OFFSET;  
        r.bottom = rect.bottom + RECTANGLE_TRACKER_OFFSET;  
  
        canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);  
  
    }  


 
4. ColorPickerPanelView
    由于此区域可做最终颜色的显示,所以也借助了AlphaPatternDrawable的实现
    此矩形区域绘制相对比较简单:


[java] view plain copy



final RectF rect = mColorRect;  
  
    if(BORDER_WIDTH_PX > 0){  
        mBorderPaint.setColor(mBorderColor);  
        canvas.drawRect(mDrawingRect, mBorderPaint);  
    }  
  
    if(mAlphaPattern != null){  
        mAlphaPattern.draw(canvas);  
    }  
  
    mColorPaint.setColor(mColor);  
  
    canvas.drawRect(rect, mColorPaint);  



至此,ColorPickerDialog主体面板绘制部分已讲述完毕.下面我会讲述另一大核心部分:颜色选择生成的交互.如果对颜色渲染方面还是不太清楚的话,可以参照我之前写的颜色渲染系列,关于原理和具体API的讲解.    

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注常用软件Photoshop频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程