Android 仿PhotoShop调色板应用(三) 主体界面绘制
版权声明:本文为博主原创文章,未经博主允许不得转载。
Android 仿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:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://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) 选择圆环绘制: 分为了内外两个圆环分别绘制. 黑色内圆及灰色外圆
具体实现请看以下代码
- /**
- * 绘制饱和度选择区域
- * @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) 颜色渲染部分仍为竖直方向的线性渐变.这里可以看一下对应颜色数组的生成:
- 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) 绘制矩形颜色选择条区域
- /**
- * 绘制右侧色相选择区域
- * @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类似
- /**
- * 绘制底部透明度选择区域
- * @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的实现
此矩形区域绘制相对比较简单:
- 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的讲解.
Android 仿PhotoShop调色板应用(三) 主体界面绘制的更多相关文章
- Android 仿PhotoShop调色板应用(四) 不同区域颜色选择的颜色生成响应
版权声明:本文为博主原创文章,未经博主允许不得转载. Android 仿PhotoShop调色板应用(四) 不同区域颜色选择的颜色生成响应 上一篇讲过了主体界面的绘制,这里讲解调色板应用中的另外一 ...
- Android 仿PhotoShop调色板应用(二) 透明度绘制之AlphaPatternDrawable
版权声明:本文为博主原创文章,未经博主允许不得转载. Android 仿PhotoShop调色板应用(二) 透明度绘制之AlphaPatternDrawable 这里讲一下如何实现PS调色板中的透明度 ...
- Android 仿PhotoShop调色板应用(一)概述
版权声明:本文为博主原创文章,未经博主允许不得转载. 在前面的系列我已经将Android中颜色渲染的原理及使用做了一个整体上概述. 现在开始根据一个比较复杂的实现进行具体的分析,这就是PhotoSho ...
- Android图形显示系统——上层显示1:界面绘制大纲
Android显示之应用界面绘制 越到上层,跟业务关联越直接.代码就越繁杂.Android上层显示的代码正是如此.此外,java语言本身繁复的特点(比C语言多了满屏的try-catch,比C++少了析 ...
- Android 仿Win8的metro的UI界面(上)
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/23441455 昨晚没事手机下载了一些APP,发现现在仿win8的主界面越来越多, ...
- Android 仿百度医生的智能分诊界面
http://blog.csdn.net/jiang89125/article/details/49622853
- Android仿人人客户端(v5.7.1)——个人主页(三)
转载请标明出处:http://blog.csdn.net/android_ls/article/details/9405089 声明:仿人人项目,所用所有图片资源都来源于其它Android移动应用,编 ...
- 安卓开发笔记(三十三):Android仿写微信发现
首先我们来看看仿写之后的效果: 看到是这个界面我们首先应该思考这些按钮是怎么做出来的?有了一个整体的思路之后才知道该怎么办.最开始我想的就直接利用button控件上面直接加上png的图片就可以形成一个 ...
- android高仿抖音、点餐界面、天气项目、自定义view指示、爬取美女图片等源码
Android精选源码 一个爬取美女图片的app Android高仿抖音 android一个可以上拉下滑的Ui效果 android用shape方式实现样式源码 一款Android上的新浪微博第三方轻量 ...
随机推荐
- MYSQL 错误 :Out of resources when opening file './datagather/mx_domain#P#p178.MYD' (Errcode: 24) 解决办法
出现Out of resources when opening file './xxx.MYD' (Errcode: 24)错误是因为打开的文件数超过了my.cnf的--open-files-limi ...
- php 删除语句
if($query&&mysql_affected_rows())echo('数据已被删除');else echo('错误,无法删除'); 通过返回影响的行数 来判断是否已经删除
- svn服务器时间与本地时间不同步解决
在用svn的时候,由于svn的时间与本地不同步,导致每次看log总是需要对时间. 今天修改了svn服务器时间与本地同步.只需要修改svn服务器时间与本地时间相同即可,但要主要修改时区,不然会出现时间又 ...
- Centos + nginx + JBOSS AS 7 搭建Java web application
最近做了一个Java的web app,一直想在Centos环境中搭建一个完整的web服务器,现在开始动手. 先说说环境: 操作系统: Centos 6.3 WEB服务器: nginx-1.2.5 Ap ...
- Warning File `.depend' has modification time 1.6 s in the future
一.前提知识 主机时间与虚拟机时间不同步所致.我们在某一操作系统所属磁盘空间下创建一个文件,那么这个文件的创建时间是以磁盘所属的操作系统的时钟为基准的. 我们假设主机windows的系统时间是10:0 ...
- NSURLSession -- 备忘
NSURLSession NSURLSession是iOS7出的API,在它之前常用的原生网络库是NSURLConnection,但是因为Connection的使用起来不是很方便 所以我们一直倾向于A ...
- 学习Swift--属性
属性 属性将值跟特定的类.结构或枚举关联.存储属性存储常量或变量作为实例的一部分,而计算属性计算(不是存储)一个值.计算属性可以用于类.结构体和枚举,存储属性只能用于类和结构体. 存储属性和计算属性通 ...
- www.nygwkt.com
南京宁阳制冷设备维修有限公司是专业从事厨房空调,http://www.nygwkt.com岗位空调制冷设备设计.制造.安装.改造.维修.保养的专业化公司.在南京享有很高的客户评论. 我们对南京宁阳制冷 ...
- 对Gearman中client,worker,jobserver的理解
在gearman的官网http://gearman.org/有以下的一段说明 A Gearman powered application consists of three parts: a clie ...
- python手记(32)
#!/usr/bin/env python #-*- coding: utf-8 -*- import cv2 import numpy as np fn="test2.jpg" ...