Android渐变研究

安卓开发   2015-12-30 09:55:25 发布
您的评价:
     
0.0
收藏     0收藏
文件夹
标签
(多个标签用逗号分隔)

下面介绍一个android实现渐变的方式

GradientDrawable

用GradientDrawable实现渐变可以通过xml或者代码实现,xml实现需要在drawable下建立xml文件,在 标签下建立 标签。

例如gradlient_background.xml文件如下:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <gradient android:startColor="#aa000000"
                      android:endColor="@android:color/transparent"
                      android:angle="90"
                />
        </shape>
    </item>
</selector>

设置方法如下:

<RelativeLayout
    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"
    >

    <LinearLayout
        android:id="@+id/layout_bottom"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:layout_alignParentBottom="true"
        android:background="@drawable/gradlient_background"
        android:orientation="horizontal"
        />

</RelativeLayout>

效果图如下:

Android渐变研究

上面的例子中我们在gradient标签中设置了startColor,endColor,angle用来表示开始结束的颜色和变化方向。 gradient标签的所有属性说明如下:

android:angle:(Integer) 渐变的角度,线性渐变时才有效,必须是45的倍数,0表示从左到右,90表示从下到上

android:centerX:(Float)渐变中心的相对X坐标,放射渐变时才有效,在0.0到1.0之间,默认为0.5,表示在正中间

android:centerY:(Float)渐变中心的相对X坐标,放射渐变时才有效,在0.0到1.0之间,默认为0.5,表示在正中间

android:centerColor :(Color)中间点的色值

android:endColor : (Color)结束的色值

android:startColor:(Color)开始的色值。

android:gradientRadius:(Float)渐变的半径,只有在android:type="radial"的时候有效。

android:type :有三种类型 "linear" 线性渐变, "radial" 放射渐变,设置该项时,android:gradientRadius也必须设置 "sweep" 扫描性渐变

android:useLevel : 如果为true,将被当成LevelListDrawable使用。

除了用xml设置,还可以在编码中设置, 标签对应的类是GradientDrawable,GradientDrawable是Drawable的子类。 代码如下:

public class TestActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new SampleView(this));
    }

    private static class SampleView extends View {
        private Rect mRect;
        private GradientDrawable mDrawable;

        public SampleView(Context context) {
            super(context);
            setFocusable(true);

            mRect = new Rect(0, 0, 300, 300);
            mDrawable = new GradientDrawable(GradientDrawable.Orientation.TL_BR,
                    new int[] { 0xaa000000,
                            0xFFFFFFFF });
            mDrawable.setShape(GradientDrawable.RECTANGLE);
            mDrawable.setGradientRadius((float)(Math.sqrt(2) * 60));
        }

        static void setCornerRadii(GradientDrawable drawable, float r0,
                                   float r1, float r2, float r3) {
            drawable.setCornerRadii(new float[] { r0, r0, r1, r1,
                    r2, r2, r3, r3 });
        }

        @Override protected void onDraw(Canvas canvas) {

            mDrawable.setBounds(mRect);

            float r = 16;

            canvas.save();
            canvas.translate(10, 10);
            mDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT);
            setCornerRadii(mDrawable, r, r, 0, 0);
            mDrawable.draw(canvas);
            canvas.restore();

            canvas.save();
            canvas.translate(10 + mRect.width() + 10, 10);
            mDrawable.setGradientType(GradientDrawable.RADIAL_GRADIENT);
            setCornerRadii(mDrawable, 0, 0, r, r);
            mDrawable.draw(canvas);
            canvas.restore();

            canvas.translate(0, mRect.height() + 10);

            canvas.save();
            canvas.translate(10, 10);
            mDrawable.setGradientType(GradientDrawable.SWEEP_GRADIENT);
            setCornerRadii(mDrawable, 0, r, r, 0);
            mDrawable.draw(canvas);
            canvas.restore();

        }
    }
}

效果如下图:

Android渐变研究

可以看到,代码设置和xml设置大同小异,注意实例化的操作:

public GradientDrawable(Orientation orientation, int[] colors) {
        this(new GradientState(orientation, colors));
    }

第一个参数是一个枚举,表示渐变方向,这个用来相当于xml里面的angle,只不过angle是用45的倍数表示方向,而枚举看上去更清楚了。

public enum Orientation {
        /** draw the gradient from the top to the bottom */
        TOP_BOTTOM,
        /** draw the gradient from the top-right to the bottom-left */
        TR_BL,
        /** draw the gradient from the right to the left */
        RIGHT_LEFT,
        /** draw the gradient from the bottom-right to the top-left */
        BR_TL,
        /** draw the gradient from the bottom to the top */
        BOTTOM_TOP,
        /** draw the gradient from the bottom-left to the top-right */
        BL_TR,
        /** draw the gradient from the left to the right */
        LEFT_RIGHT,
        /** draw the gradient from the top-left to the bottom-right */
        TL_BR,
    }

第二个参数是一个color数组,相当于startColor,endColor,centerColor,其中centerColor可以省略,但是至少要设置两个颜色。 mDrawable.setGradientType可以设置三种type同xml一样,分别是GradientDrawable.LINEAR_GRADIENT,GradientDrawable .RADIAL_GRADIENT,GradientDrawable.SWEEP_GRADIENT。

Shader类的子类

Shader类的子类创建允许使用多种固体颜色填充绘图对象的Paint,功能不只是实现渐变填充。有三Shader是用来做渐变的: LinearGradient、RadialGradient和 SweepGradient. 看名字就知道这三种和上面的GradientDrawable的三种type是对应的。 只不过是用Shader实现了。

要在绘图的时候使用一个Shader,可以使用setShader方法将其应用到一个Paint中,如下面的代码所示:

Paint shaderPaint = new Paint();  
    shaderPaint.setShader(myLinearGradient);

使用这个Paint所绘制的任何东西都将使用你指定的Shader进行填充,而不是使用Paint本身的颜色进行填充。下面使用LinearGradient实现渐变,对于RadialGradient和 SweepGradient使用很类似。

public class TestActivity extends Activity {
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(new SampleView(this));
            }
        
            private static class SampleView extends View {
                private Paint mPaint;
                private Rect mRect;
                LinearGradient lg1 ;
                LinearGradient lg2 ;
                LinearGradient lg3 ;
        
                public SampleView(Context context) {
                    super(context);