zoukankan      html  css  js  c++  java
  • android-关于颜色渐变

    引子

    颜色渐变一般两种方式(好像是废话额,因为凡是涉及到特效或者动画,基本都是两种方式··) 

    一种是写XML配置,一种是写纯代码;下面分别就两个种方式给出demo;

     

    方式1

    在drawable/目录下创建一个文件gradient.xml,内容如下:

    <shape xmlns:android="http://schemas.android.com/apk/res/android">
        <gradient
            android:angle="0"
            android:endColor="@android:color/holo_red_light"
            android:startColor="@android:color/holo_green_light" />
    </shape>

    然后给某个view指定background:

     <View
                     android:layout_width="@dimen/shape_width"
                     android:layout_height="@dimen/shape_width"
                     android:background="@drawable/gradient" />

    实际效果如下:

      

     

    上面的gradient,我们用了3个属性:angle角度,startColor,endColor起始和结束的颜色;

    起始结束颜色好理解,这里的这个angle,其实我们还可以指定为其他值,上面指定0 ,我们得到了一个从左到右的渐变;

    此外还可以指定,  

       0 是从左到右渐变;45是从左下角向右上角渐变;90是从下到上,135是从右下角到左上角;180则是从右到左;(当然也可以是 -45,-90....)

     

     

    优点:简单有效。足以应付大部分的渐变需求;
    缺点: 不够灵活,不能满足高级需求。而且不支持任意角度(很诡异,只支持45的倍数);

     方式二

    利用LinearGradient + Paint + 自定义View;

    由于是纯代码实现,我就直接帖代码了;重点看红色文字部分;

     1 package com.example.colorstudy;
     2 
     3 import android.content.Context;
     4 import android.content.res.TypedArray;
     5 import android.graphics.Canvas;
     6 import android.graphics.Color;
     7 import android.graphics.LinearGradient;
     8 import android.graphics.Paint;
     9 import android.graphics.Shader;
    10 import android.support.annotation.Nullable;
    11 import android.util.AttributeSet;
    12 import android.view.View;
    13 
    14 public class GradientDemoView extends View {
    15 
    16     public GradientDemoView(Context context) {
    17         this(context, null);
    18     }
    19 
    20     public GradientDemoView(Context context, @Nullable AttributeSet attrs) {
    21         this(context, attrs, 0);
    22     }
    23 
    24     public GradientDemoView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    25         super(context, attrs, defStyleAttr);
    26         initAttrs(context, attrs);
    27     }
    28 
    29     private int mode;
    30 
    31     private void initAttrs(Context context, AttributeSet attrs) {
    32         TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.GradientDemoView);
    33         if (null != ta) {
    34             mode = ta.getInteger(R.styleable.GradientDemoView_mode, 0);
    35         }
    36     }
    37 
    38     @Override
    39     protected void onDraw(Canvas canvas) {
    40         super.onDraw(canvas);
    41 
    42         int width = getWidth();
    43         int height = getHeight();
    44 
    45         int colorStart = Color.RED;
    46         int color1 = Color.GREEN;
    47         int colorEnd = Color.BLUE;
    48 
    49         Paint paint = new Paint();
    50 
    51         //重点解析这里的渐变配置
    52 /**
    53  * Create a shader that draws a linear gradient along a line.   创建一个沿着"一条线"绘制线性渐变的着色器?
    54  *
    55  * @param x0           "一条线"开始位置的X   - 这个坐标是以 左上角为原点,对哦,android里面所有的绘制都是以控件左上角为原点(0,0)
    56  * @param y0           "一条线"开始位置的Y
    57  * @param x1           "一条线"结束为止的X
    58  * @param y1           "一条线"结束为止的Y
    59  * @param colors       颜色数组,可以是3个以上
    60  * @param positions    颜色分段权重:比如说,有3种颜色,红绿蓝渐变,这里的positions的值是new float[]{0, 0.75f, 1f};
    61  *                     则,0到0.75这一段,是红色渐变为绿色,0.75到1这一段是 绿色渐变为蓝色;
    62  * @param tile         填充模式?
    63  *                     详解:
    64  *                     CLAMP : 重复最后一种颜色直到View结束(当你的起始结束的坐标并没有覆盖整个View,那么这种模式将会用最后一种颜色填充剩余的部分)
    65  *                     REPEAT: 当你的起始结束的坐标并没有覆盖整个View,这种模式将会进行颜色的重新渐变;
    66  *                     MIRROR: 镜像模式绘制,当你的起始结束的坐标并没有覆盖整个View,剩余的部分将会尽量和已经绘制的部分颜色对称;
    67  */
    68         LinearGradient backGradient = null;
    69         if (mode == 0) {
    70             backGradient = new LinearGradient(0, 0, 0, height / 2,
    71                     new int[]{colorStart, color1, colorEnd}, new float[]{0, 0.75f, 1f}, Shader.TileMode.CLAMP);
    72         } else if (mode == 1) {
    73             backGradient = new LinearGradient(0, 0, 0, height / 2,
    74                     new int[]{colorStart, color1, colorEnd}, new float[]{0, 0.75f, 1f}, Shader.TileMode.REPEAT);
    75         } else if (mode == 2) {
    76             backGradient = new LinearGradient(0, 0, 0, height / 2,
    77                     new int[]{colorStart, color1, colorEnd}, new float[]{0, 0.75f, 1f}, Shader.TileMode.MIRROR);
    78         }
    79 
    80 
    81         paint.setShader(backGradient);
    82         canvas.drawRect(0, 0, width, height, paint);
    83 
    84     }
    85 
    86 
    87 }

    其他文件:res/values/attr.xml

    <resources>
        <declare-styleable name="GradientDemoView">
            <attr name="mode" format="integer" />
        </declare-styleable>
    </resources>

    res/values/dimens.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <dimen name="shape_width">30dp</dimen>
    </resources>

    使用此控件的xml:

    <GridLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:columnCount="2"
            android:rowCount="2">
    
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:gravity="center"
                android:orientation="horizontal">
    
                <com.example.colorstudy.GradientDemoView
                    android:layout_width="@dimen/shape_width"
                    android:layout_height="@dimen/shape_width"
                    app:mode="0" />
    
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="30dp"
                    android:text="CLAMP模式" />
            </LinearLayout>
    
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:gravity="center"
                android:orientation="horizontal">
    
                <com.example.colorstudy.GradientDemoView
                    android:layout_width="@dimen/shape_width"
                    android:layout_height="@dimen/shape_width"
                    app:mode="1" />
    
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="30dp"
                    android:text="REPEAT模式" />
            </LinearLayout>
    
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:gravity="center"
                android:orientation="horizontal">
    
                <com.example.colorstudy.GradientDemoView
                    android:layout_width="@dimen/shape_width"
                    android:layout_height="@dimen/shape_width"
                    app:mode="2" />
    
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="30dp"
                    android:text="MIRROR模式 " />
            </LinearLayout>
        </GridLayout>

     实际效果:

     

    优点:几乎能够满足你能想到的所有渐变需求,处理起来很灵活;渐变色可以是3个以上,每种颜色占比多少可以自己调节,渐变的模式自己指定;而且还可以顺带加上其他特效,就这一点,xml写配置就无法比拟;

    缺点:如果是较为复杂的渐变,对开发人员要求就比较高了,而且还 可能涉及到什么数学算法之类的,数学渣一脸泪有木有·····

    ok就酱紫咯。喜欢的大佬,欢迎复制; 

     

     

     

     

     

  • 相关阅读:
    053-649
    053-648
    053-647
    053-646
    053-645
    053-644
    053-643
    053-642
    053-641
    053-640
  • 原文地址:https://www.cnblogs.com/hankzhouAndroid/p/9505254.html
Copyright © 2011-2022 走看看