LinearGradient我们可以将之译为线型渐变、线型渲染等,译成什么不重要,重要的是它的显示效果是什么样子,今天我们就一起来看看。

先来看看LinearGradient的构造方法:

    /** Create a shader that draws a linear gradient along a line.
@param x0 The x-coordinate for the start of the gradient line
@param y0 The y-coordinate for the start of the gradient line
@param x1 The x-coordinate for the end of the gradient line
@param y1 The y-coordinate for the end of the gradient line
@param colors The colors to be distributed along the gradient line
@param positions May be null. The relative positions [0..1] of
each corresponding color in the colors array. If this is null,
the the colors are distributed evenly along the gradient line.
@param tile The Shader tiling mode
*/
public LinearGradient(float x0, float y0, float x1, float y1, int colors[], float positions[],
TileMode tile) {
.........
.....
......
}

LinearGradient的构造方法共有七个参数,分别表示:

x0表示渲染起始位置的x坐标,y0表示渲染起始位置的y坐标,x1表示渲染结束位置的x坐标,y1表示渲染结束位置的y坐标,colors表示渲染的颜色,它是一个颜色数组,数组长度必须大于等于2,positions表示colors数组中几个颜色的相对位置,是一个float类型的数组,该数组的长度必须与colors数组的长度相同。如果这个参数使用null也可以,这时系统会按照梯度线来均匀分配colors数组中的颜色,最后一个参数则表示平铺方式,有三种,我们分别来看:

为了给大家演示不同平铺方式下使用着色器的不同效果,我自定义了一个View,叫做AboutShaderView,我重写了该View中的两个方法,分别是onMeasure以及onDraw,在onMeasure方法中,我把该控件的宽高固定为256dp,代码如下:

    @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension((int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 256, getResources().getDisplayMetrics()), (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 256, getResources().getDisplayMetrics()));
}

然后在onDraw方法中通过使用着色器的不同模式,来让它显示不同的效果,最后,我在布局文件中引用自定义View:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="lenve.customtextview.MainActivity">
<lenve.customtextview.AboutShaderView
android:layout_width="256dp"
android:layout_height="256dp"/>
</LinearLayout>

OK,下面我们一起来看看这几种不同模式的显示效果:

1.LinearGradient.TileMode.CLAMP

这种模式表示重复最后一种颜色直到该View结束的地方,如果我设置着色器开始的位置为(0,0),结束位置为(getMeasuredWidth(), 0)表示我的着色器要给整个View在水平方向上渲染不同的颜色,代码如下:

    @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.GREEN);
LinearGradient linearGradient = new LinearGradient(0, 0, getMeasuredWidth(), 0,new int[]{Color.RED, Color.WHITE, Color.BLUE}, null, LinearGradient.TileMode.CLAMP);
paint.setShader(linearGradient);
canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),paint);
}

显示效果如下:

水平方向上依次是红白蓝,没问题,那我如果变换一下需求,我想把渲染的方向修改为从左上角到右下角,那么该怎么办?很简单,只需要修改渲染结束的位置为getMeasuredHeight()即可,代码如下:

    @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.GREEN);
LinearGradient linearGradient = new LinearGradient(0, 0, getMeasuredWidth(), getMeasuredHeight(),new int[]{Color.RED, Color.WHITE, Color.BLUE}, null, LinearGradient.TileMode.CLAMP);
paint.setShader(linearGradient);
canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),paint);
}

显示效果如下:

OK,两个小Demo让大家先感受下Shader,下面我继续变换的我的需求,如果我希望我的着色器的渲染位置变为从(0,0)到(getMeasuredWidth()/2, 0),那么这时候的渲染区域是什么呢?如下图:

OK,也就是说控件只有一半会被渲染,那么剩下的一半怎么办呢?这时候就得看我们的最后一个参数了,我们已经说过,LinearGradient.TileMode.CLAMP模式表示重复最后一种颜色直到该View结束的地方,也就是说从View宽度的1/2处直到View结束的地方都将是蓝色(因为View1/2处的颜色是蓝色),那么究竟是不是呢,我们看代码:

    @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.GREEN);
LinearGradient linearGradient = new LinearGradient(0, 0, getMeasuredWidth()/2, 0,new int[]{Color.RED, Color.WHITE, Color.BLUE}, null, LinearGradient.TileMode.CLAMP);
paint.setShader(linearGradient);
canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),paint);
}

再看效果图:

和我们想的一样,这就是LinearGradient.TileMode.CLAMP模式的特点。

2.LinearGradient.TileMode.REPEAT

LinearGradient.TileMode.REPEAT表示着色器在水平或者垂直方向上对控件进行重复着色,类似于windows系统桌面背景中的“平铺”,那么接下来我们来看看着色器对这种模式的处理方式,假如我希望着色器开始渲染的位置为(0,0),结束渲染的位置为(getMeasuredWidth()/2, getMeasuredHeight()/2),但与之前不同的是这次的平铺方式变为LinearGradient.TileMode.REPEAT,我们来看看代码:

    @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.GREEN);
LinearGradient linearGradient = new LinearGradient(0, 0, getMeasuredWidth()/2, getMeasuredHeight()/2,new int[]{Color.RED, Color.WHITE, Color.BLUE}, null, LinearGradient.TileMode.REPEAT);
paint.setShader(linearGradient);
canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),paint);
}

效果图如下:

OK,沿着举行对角线,着色器对View进行了重复渲染,为了大家更好的理解LinearGradient.TileMode.REPEAT模式,这次我把我的需求该一下,我希望从(0,0)处开始渲染,到(0, getMeasuredHeight()/2)处结束,这时系统会在垂直方向上重复渲染,代码如下:

    @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.GREEN);
LinearGradient linearGradient = new LinearGradient(0, 0, 0, getMeasuredHeight()/2,new int[]{Color.RED, Color.WHITE, Color.BLUE}, null, LinearGradient.TileMode.REPEAT);
paint.setShader(linearGradient);
canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),paint);
}

效果图如下:

OK,没问题,如我们所预料的那样。

3.LinearGradient.TileMode.MIRROR

LinearGradient.TileMode.MIRROR模式会在水平方向或者垂直方向上以镜像的方式进行渲染,这种渲染方式的一个特征就是具有翻转的效果,比如我希望我的着色器开始渲染的位置为(0,0),结束渲染的位置为(getMeasuredWidth()/2, 0),那么效果图是什么样子呢?我们先来看看代码:

    @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.GREEN);
LinearGradient linearGradient = new LinearGradient(0, 0, getMeasuredWidth()/2, 0,new int[]{Color.RED, Color.WHITE, Color.BLUE}, null, LinearGradient.TileMode.MIRROR);
paint.setShader(linearGradient);
canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),paint);
}

效果图如下:

OK,剩下的一部分依然被渲染,但是渲染的前后两部分是对称的,这就是LinearGradient.TileMode.MIRROR模式,很简单吧!

OK,以上就是LinearGradient的用法,有问题欢迎讨论。

关于着色器LinearGradient的使用的更多相关文章

  1. D3D三层Texture纹理经像素着色器实现渲染YUV420P

    简单记录一下这两天用Texture实现渲染YUV420P的一些要点. 在视频播放的过程中,有的时候解码出来的数据是YUV420P的.表面(surface)通过设置参数是可以渲染YUV420P的,但Te ...

  2. 片元着色器(Fragment Shader)被称为像素着色器(Pixel Shader),但

    片元着色器(Fragment Shader)被称为像素着色器(Pixel Shader),但片元着色器是一个更合适的名字, 因为此时的片元并不是一个真正意义上的像素.

  3. [Unity] Shader(着色器)输入输出和语义

    在Unity5.x后, 已经支持了基于物理的光照模型,也就是常说的次时代引擎所必须具备的功能. 如果在Properties使用2D,CG里要用sampler2D,代表使用的是2维纹理 如果在Prope ...

  4. [Unity] Shader(着色器)之纹理贴图

    在Shader中,我们除了可以设定各种光线处理外,还可以增加纹理贴图. 使用 settexture 命令可以为着色器指定纹理. 示例代码: Shader "Sbin/ff2" { ...

  5. OpenGL管线(用经典管线代说着色器内部)

    图形管线(graphics pipeline)向来以复杂为特点,这归结为图形任务的复杂性和挑战性.OpenGL作为图形硬件标准,是最通用的图形管线版本.本文用自顶向下的思路来简单总结OpenGL图形管 ...

  6. 【OPENGL】第三篇 着色器基础(二)

    在这一小节,主要学习GLSL的基本数据类型以及控制结构.GLSL具备了C++和Java的很多特性,我们会先了解所有着色阶段共有的特性,再了解各个着色器的专属特性. 1.着色器的基本结构 一个着色器程序 ...

  7. 【OPENGL】第三篇 着色器基础(一)

    在这一章,我们会学习什么是着色器(Shader),什么是着色器语言(OpenGL Shading Language-GLSL),以及着色器怎么和OpenGL程序交互. 首先我们先来看看什么叫着色器. ...

  8. Unity3d 着色器语法(Shader)

    Shader "name" { [Properties] Subshaders [Fallback] } 定义了一个着色器.着色器拥有一个 Properties 的列表.着色器包含 ...

  9. OpenGL官方教程——着色器语言概述

    OpenGL官方教程——着色器语言概述 OpenGL官方教程——着色器语言概述 可编程图形硬件管线(流水线) 可编程顶点处理器 可编程几何处理器 可编程片元处理器 语言 可编程图形硬件管线(流水线) ...

随机推荐

  1. linux下跨服务器文件文件夹的复制

    文件的复制:scp –P (端口号) ./authorized_keys berchina@hadoop002:/home/berchina 文件夹的复制:scp -r -P (端口号) /home/ ...

  2. URAL1244. Gentlemen(背包)

    链接 以前做的题 VJ太水了 数组里面的数可能会小于0 当时没判断 #include <iostream> #include<cstdio> #include<cstri ...

  3. [LeetCode#272] Closest Binary Search Tree Value II

    Problem: Given a non-empty binary search tree and a target value, find k values in the BST that are ...

  4. POJ_1269_Intersecting_Lines_(计算几何基础)

    描述 http://poj.org/problem?id=1269 给出两条直线,判断它们是平行,重合,还是相交,如果相交,求出交点. 分析 比较裸的一道题.学习了直线的写法(参数方程) #inclu ...

  5. $apply() $digest()

    理解Angular中的$apply()以及$digest() <!DOCTYPE html> <html> <head> <meta charset=&quo ...

  6. 全新 D 系列虚拟机型号

    Kenaz KwaAzure计算运行时项目经理 今天,我们宣布将发布名为D系列的Windows Azure 新VM型号,并支持虚拟机和 Web/Worker Role.这些虚拟机型号最多可以提供 11 ...

  7. 两种应该掌握的排序方法--------2.quick Sort

    介绍 http://zh.wikipedia.org/wiki/%E5%BF%AB%E9%80%9F%E6%8E%92%E5%BA%8F 用些里面的c++ 实现,感觉这个空间复杂度比较小.还挺好 in ...

  8. UVa 11752 - The Super Powers 数学

    请看这个说明http://blog.csdn.net/u014800748/article/details/45914353 #define _CRT_SECURE_NO_WARNINGS #incl ...

  9. 尝试加载 Oracle 客户端库时引发 BadImageFormatException。如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题。

    从10G开始,Oracle提供了一个较为轻量级的客户包,叫做Instant Client. 将它安装好后,就不用再安装庞大的Oracle Client了. 这样一来,只要客户端下载Instant Cl ...

  10. noip 2014 子矩阵

    先枚举行再DP列.好题,详见代码 #include <cstdio> #include <cstring> #include <cstdlib> #include ...