自定义控件(阴影,渐变)

一、阴影:
Paint 类定义了一个名为 setShadowLayer 的方法:
public void setShadowLayer(float radius,float dx,float dy,int shadowColor), 参数意义如下:
radius:阴影半径
dx: x 方向阴影的偏移量
dy: y 方向阴影的偏移量
shadowColor: 阴影的颜色
阴影layer显示 影时,shaderlayer 有 两 种 类 型 : View.LAYER_TYPE_SOFTWARE 和View.LAYER_TYPE_HARDWARE, layer 的默认类型为 LAYER_TYPE_HARDWARE, 但阴影只能在
View.LAYER_TYPE_SOFTWARE 环 境 下 工 作 , 所 以 , 我 们 需 要 调 用 View 类 的 public void setLayerType(int layerType,Paint paint) 方 法 为 Paint 对 象 指 定 层 的 类 型 :
setLayerType(View.LAYER_TYPE_SOFTWARE, paint)。如想取消阴影则将radius设置为0.

ShaderView.java:

public class ShaderView extends View {
    private Paint paint;
    public ShaderView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ShaderView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStrokeWidth(5);
        paint.setTextSize(100);
        this.setLayerType(View.LAYER_TYPE_SOFTWARE,paint);//设置为SOFTWARE才会实现阴影
        paint.setShadowLayer(10,1,1, Color.BLUE);//偏移度很小时则变成发光字体
        canvas.drawText("Android开发",100,100,paint);
        canvas.restore();
        paint.setShadowLayer(10,5,5,Color.GREEN);//如果想要取消阴影,则将Radius设为0即可
        canvas.drawText("Android,你好",100,400,paint);
    }
}


二、渐变
渐变种类有:
1. 线性渐变: LinearGradient
线性渐变( LinearGradient) 根据指定的角度、颜色和模式使用渐变颜色填充绘图区域。我们必须定义两个点( x0, y0)和( x1, y1),渐变的方向与这两个点的连线垂直,
LinearGradient 的构造方法如下:
<1>
public LinearGradient(float x0,float y0,float x1,float y1,int color0,int color1,TileMode tile):本方法用于两种颜色的渐变, 各参数意义如下:
x0、 y0: 用于决定线性方向的第一个点的坐标( x0, y0);
x1、 y1:用于决定线性方向的第二个点的坐标( x1, y1);
color0: 第一种颜色;
color1: 第二种颜色;
tile: 渐变模式
<2>
public LinearGradient(float x0,float y0,float x1,float y1,int colors[],float positions[],TileMode tile), 这是一个功能更加强大的构造方法, 我们来看看该构造方法参数的作用:
x0、 y0:起始点的坐标
x1、 y1:终止点的坐标
colors:多种颜色
positions:颜色的位置(比例)
TileMode:渐变模式
参数 colors 和 positions 都是数组, 前者用于指定多种颜色,后者用于指定每种颜色的起始比例位置。 positions 数组中的元素个数与 colors 要相同, 且是 0 至 1 的数值, [0,1]是临界区, 
如果小于 0 则当 0 处理, 如果大于 1 则当 1 处理。假如在绘图区域和渐变区域大小相同的情况下,colors 包含了三种颜色: red、 yellow、 green, 在渐变区域中这三种颜色的起始比例位置为 0、 0.3、


2. 径向渐变: RadialGradient
径向渐变是以指定的点为中心, 向四周以渐变颜色进行圆周扩散, 和线性渐变一样,支持两种或多种颜色。
<1>public RadialGradient(float x,float y,float radius, int color0,int color1, TileMode tile), 该构造方法支持两种颜色, 下面是参数的作用:
x、 y: 中心点坐标
radius: 渐变半径
color0:起始颜色
color1:结束颜色
TileMode:渐变模式
<2>public RadialGradient(float x,float y,float radius, int colors[],float positions[], TileModetile), 该构造方法支持 3 种或 3 种以上颜色的渐变, 各参数的作用如下:
x、 y: 中心点坐标
radius: 渐变半径
colors:多种颜色
positions:颜色的位置(比例)
TileMode:渐变模式
构造函数2用法如上;

3. 扫描渐变: SweepGradient
SweepGradient 类似于军事题材电影中的雷达扫᧿效果, 固定圆心, 将半径假想为有形并旋
转一周而绘制的渐变颜色。 SweepGradient 定义了两个主要的构造方法:
<1>public SweepGradient(float cx,float cy,int color0,int color1)
支持两种颜色的扫描渐变, 参数的作用如下:
cx、 cy:圆点坐标;
color0:起始颜色;
color1:结束颜色。
<2>public SweepGradient(float cx,float cy,int colors[],float positions[])
支持多种颜色的扫描渐变, 参数的作用如下:
cx、 cy:圆点坐标;
colors:多种颜色;
positions:颜色的位置(比例)。


4. 位图渐变: BitmapShader
位图渐变其实就是在绘制的图形中将指定的位图作为背景, 如果图形比位图小, 则通过渐变模式进行平铺, TileMode.CLAMP 模式不平铺, TileMode.REPEAT 模式表示平铺, TileMode.MIRROR
模式也表示平铺, 但是交错的位图是彼此的镜像, 方向相反。 可以同时指定水平和垂直两个方向的渐变模式。
构造方法:
public BitmapShader(Bitmap bitmap,TileMode tileX,TileMode tileY), 参数如下:
bitmap:位图;
tileX: x 方向的重复模式;
tileY: y 方向的重复模式。


5. 混合渐变: ComposeShader
混合渐变 ComposeShader是将两种不同的渐变通过位图运算后得到的一种更加复杂的渐变。
构造方法:
<1>public ComposeShader(Shader shaderA,Shader shaderB,Xfermode mode)
<2>public ComposeShader(Shader shaderA,Shader shaderB,Mode mode)
shaderA 和 shaderB 是两个渐变对象, mode 为位图运算类型, 16 种运算模式如图 5-15
所示:


代码中, shaderA 为位图渐变, shaderB 为线性渐变, 根据 Mode.SRC_ATOP 的运算规则,
shaderA 会全部显示( 此处为小机器人), shaderB 只显示二者相交部分并位于最上面( TOP)。

渐变效果代码:

public class RadialGradientView extends View {
    private int color[]={Color.GREEN,Color.BLUE,Color.RED};
    //private float position[]={0,0.5f,1};
    public RadialGradientView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public RadialGradientView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Rect rect=new Rect(100,100,600,600);
        //1.径向渐变
        RadialGradient r=new RadialGradient(350,350,250, Color.BLUE,Color.YELLOW, Shader.TileMode.MIRROR);
        //2.线性渐变
      //  LinearGradient r=new LinearGradient(100,100,600,600,Color.RED,Color.GREEN, Shader.TileMode.CLAMP);
        //3.扫描渐变
       // SweepGradient r=new SweepGradient(350,350,Color.RED,Color.GREEN);
        //SweepGradient r=new SweepGradient(350,350,color,null);
        //4.位图渐变
//        Bitmap bitmap= BitmapFactory.decodeResource(getResources(),R.drawable.boy);
//        BitmapShader r=new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.MIRROR);
        //5.混合渐变
//        LinearGradient lg=new LinearGradient(100,100,600,600,Color.RED,Color.GREEN, Shader.TileMode.CLAMP);
//        Bitmap bitmap= BitmapFactory.decodeResource(getResources(),R.drawable.boy);
//        BitmapShader bs=new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.MIRROR);
//        ComposeShader r=new ComposeShader(bs,lg, PorterDuff.Mode.SRC_ATOP);
        //公用部分
        Paint paint=new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setShader(r);
        canvas.drawRect(rect,paint);
        canvas.translate(0,500);
        canvas.drawOval(new RectF(rect),paint);
    }
}

渐变与Matrix
public void setLocalMatrix(Matrix localM), 该方法能和渐变结合,在填充渐变颜色的时候实现移位、旋转、缩放和拉斜的效果。

我们做一个旋转的圆, 圆内使用 SweepGradient 渐变填充,看起来像一张光盘。首先, 我们创建了一个 Matrix 对象 mMatrix, mMatrix 定义了以圆点为中心渐变的旋转效
果, 注意不是旋转 Canvas 而是旋转 SweepGradient。 onDraw()方法中不断调用 invalidate()重绘自己, 每重绘一次就旋转 2 度,于是就形成了一个旋转的动画。

SweepMatrixView.java:

public class SweepMatrixView extends View {
    private Paint mpaint=new Paint(Paint.ANTI_ALIAS_FLAG);
    private float mRotate;
    private Matrix matrix=new Matrix();
    private Shader mshader;
    private int[] color={ Color.GREEN,Color.RED,Color.BLUE};
    public SweepMatrixView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setFocusable(true);
        setFocusableInTouchMode(true);

        float x=100;
        float y=100;
        mshader=new SweepGradient(x,y,color,null);
        mpaint.setShader(mshader);
    }

    public SweepMatrixView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint =mpaint;
        float x=100;
        float y=100;
        canvas.translate(100,100);
        canvas.drawColor(Color.WHITE);
        matrix.setRotate(mRotate,x,y);
        mshader.setLocalMatrix(matrix);
        mRotate+=2;
        if(mRotate>=360){
            mRotate=0;
        }
        invalidate();
        canvas.drawCircle(x,y,100,paint);
    }
}
可以实现扫描渐变像光盘一样旋转。

猜你喜欢

转载自blog.csdn.net/fuzhongbin/article/details/51321469