Tuesday, November 10, 2015

android - How to apply TextView text color Gradient

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/rl"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity"
    >
    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textStyle="bold"
        android:textSize="90dp"
        android:fontFamily="sans-serif-condensed"
        android:textColor="#000"
        />
    <Button
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Apply Gradient Text"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        />
    <RadioGroup
        android:id="@+id/rg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        >
        <RadioButton
            android:id="@+id/rb_normal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Normal"
            android:checked="true"
            />
        <RadioButton
            android:id="@+id/rb_emboss"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Emboss"
            />
        <RadioButton
            android:id="@+id/rb_deboss"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Deboss"
            />
    </RadioGroup>
</RelativeLayout>
MainActivity.java

package com.cfsuman.me.androidcode;

import android.content.Context;
import android.graphics.EmbossMaskFilter;
import android.graphics.Point;
import android.graphics.Shader;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.RadioGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;

import java.util.Random;


public class MainActivity extends AppCompatActivity {
    private Context mContext;
    private RelativeLayout mRL;
    private TextView mTV;
    private Button mBTN;
    private RadioGroup mRG;
    private int mWidth;
    private int mHeight;
    private Random mRandom = new Random();
    private Shader shader;

    private GradientManager mGradientManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Get the application context
        mContext = getApplicationContext();

        // Get the widgets reference from XML layout
        mRL = (RelativeLayout) findViewById(R.id.rl);
        mTV = (TextView) findViewById(R.id.tv);
        mBTN = (Button) findViewById(R.id.btn);
        mRG = (RadioGroup) findViewById(R.id.rg);

        // Set a click listener for Button widget
        mBTN.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Get the TextView width and height in pixels
                mWidth = mTV.getWidth();
                mHeight = mTV.getHeight();
                Point size = new Point(mWidth,mHeight);

                // Initializing a new instance of GradientManager class
                mGradientManager = new GradientManager(mContext,size);

                // Get a random indicator to define next gradient type
                int indicator = mRandom.nextInt(3);

                if(indicator == 0){
                    shader = mGradientManager.getRandomLinearGradient();
                    mTV.setText("Linear Gradient");
                }else if(indicator == 1){
                    shader = mGradientManager.getRandomRadialGradient();
                    mTV.setText("Radial Gradient");
                }else {
                    shader = mGradientManager.getRandomSweepGradient();
                    mTV.setText("Sweep Gradient");
                }

                /*
                    public void setLayerType (int layerType, Paint paint)
                        Specifies the type of layer backing this view. The layer can be LAYER_TYPE_NONE,
                        LAYER_TYPE_SOFTWARE or LAYER_TYPE_HARDWARE.

                        A layer is associated with an optional Paint instance that controls how the
                        layer is composed on screen.

                    Parameters
                        layerType : The type of layer to use with this view, must be one of
                            LAYER_TYPE_NONE, LAYER_TYPE_SOFTWARE or LAYER_TYPE_HARDWARE
                        paint : The paint used to compose the layer. This argument is optional and
                            can be null. It is ignored when the layer type is LAYER_TYPE_NONE
                */
                /*
                    public static final int LAYER_TYPE_SOFTWARE
                        Indicates that the view has a software layer. A software layer is backed by
                        a bitmap and causes the view to be rendered using Android's software rendering
                        pipeline, even if hardware acceleration is enabled.
                */
                mTV.setLayerType(View.LAYER_TYPE_SOFTWARE,null);

                /*
                    Paint
                        The Paint class holds the style and color information about how to draw
                        geometries, text and bitmaps.
                */
                /*
                    Shader
                        Known Direct Subclasses
                        BitmapShader, ComposeShader, LinearGradient, RadialGradient, SweepGradient

                        Shader is the based class for objects that return horizontal spans of colors
                        during drawing. A subclass of Shader is installed in a Paint calling
                        paint.setShader(shader). After that any object (other than a bitmap) that
                        is drawn with that paint will get its color(s) from the shader.
                */
                mTV.getPaint().setShader(shader);
            }
        });

        // Set a checked change listener for RadioGroup
        mRG.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int i) {
                if (i == R.id.rb_normal) {
                    // Remove the mask filter
                    mTV.getPaint().setMaskFilter(null);
                } else if (i == R.id.rb_emboss) {
                    /*
                        MaskFilter
                            MaskFilter is the base class for object that perform transformations on an
                            alpha-channel mask before drawing it. A subclass of MaskFilter may be installed
                            into a Paint. Blur and emboss are implemented as subclasses of MaskFilter.
                    */
                    /*
                        public EmbossMaskFilter (float[] direction, float ambient, float specular,
                            float blurRadius)

                        Create an emboss maskfilter

                        Parameters
                            direction : array of 3 scalars [x, y, z] specifying the direction of the
                                light source
                            ambient : 0...1 amount of ambient light
                            specular : coefficient for specular highlights (e.g. 8)
                            blurRadius : amount to blur before applying lighting (e.g. 3)
                        Returns
                            the emboss maskfilter
                    */
                    EmbossMaskFilter embossFilter = new EmbossMaskFilter(
                            new float[]{1f, 5f, 1f}, // direction of the light source
                            0.8f, // ambient light between 0 to 1
                            8, // specular highlights
                            7f // blur before applying lighting
                    );
                    // Apply the emboss mask filter
                    mTV.getPaint().setMaskFilter(embossFilter);
                } else if (i == R.id.rb_deboss) {
                    EmbossMaskFilter debossFilter = new EmbossMaskFilter(
                            new float[]{0f, -1f, 0.5f}, // direction of the light source
                            0.8f, // ambient light between 0 to 1
                            13, // specular highlights
                            7.0f // blur before applying lighting
                    );
                    // Apply the deboss mask filter
                    mTV.getPaint().setMaskFilter(debossFilter);
                }
            }
        });
    }
}
GradientManager.java

package com.cfsuman.me.androidcode;

import android.content.Context;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Point;
import android.graphics.RadialGradient;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import java.util.Random;


public class GradientManager {
    private Random mRandom = new Random();
    private Context mContext;
    private Point mSize;

    public GradientManager(Context context, Point size){
        this.mContext = context;
        this.mSize = size;
    }

    // Custom method to generate a random LinearGradient
    protected LinearGradient getRandomLinearGradient(){
        /*
            public LinearGradient (float x0, float y0, float x1, float y1, int[] colors, float[]
                positions, Shader.TileMode tile)

                Create a shader that draws a linear gradient along a line.

                Parameters
                x0 : The x-coordinate for the start of the gradient line
                y0 : The y-coordinate for the start of the gradient line
                x1 : The x-coordinate for the end of the gradient line
                y1 : The y-coordinate for the end of the gradient line
                colors : The colors to be distributed along the gradient line
                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.
                tile : The Shader tiling mode
        */

        LinearGradient gradient = new LinearGradient(
                0,
                0,
                mSize.x,
                mSize.y,
                getRandomColorArray(), // Colors to draw the gradient
                null, // No position defined
                getRandomShaderTileMode() // Shader tiling mode
        );
        // Return the LinearGradient
        return gradient;
    }

    // Custom method to generate a random RadialGradient
    protected RadialGradient getRandomRadialGradient(){
        /*
            public RadialGradient (float centerX, float centerY, float radius, int[] colors,
                float[] stops, Shader.TileMode tileMode)

                Create a shader that draws a radial gradient given the center and radius.

                Parameters
                    centerX : The x-coordinate of the center of the radius
                    centerY : The y-coordinate of the center of the radius
                    radius : Must be positive. The radius of the circle for this gradient.
                    colors : The colors to be distributed between the center and edge of the circle
                    stops : May be null. Valid values are between 0.0f and 1.0f. The relative
                        position of each corresponding color in the colors array. If null, colors
                        are distributed evenly between the center and edge of the circle.
                    tileMode : The Shader tiling mode
        */
        RadialGradient gradient = new RadialGradient(
                mRandom.nextInt(mSize.x),
                mRandom.nextInt(mSize.y),
                mRandom.nextInt(mSize.x),
                getRandomColorArray(),
                null, // Stops position is undefined
                getRandomShaderTileMode() // Shader tiling mode

        );
        // Return the RadialGradient
        return gradient;
    }

    // Custom method to generate a random SweepGradient
    protected SweepGradient getRandomSweepGradient(){
        /*
            public SweepGradient (float cx, float cy, int[] colors, float[] positions)
                A subclass of Shader that draws a sweep gradient around a center point.

                Parameters
                cx : The x-coordinate of the center
                cy : The y-coordinate of the center
                colors : The colors to be distributed between around the center. There must be at
                    least 2 colors in the array.
                positions : May be NULL. The relative position of each corresponding color in the
                    colors array, beginning with 0 and ending with 1.0. If the values are not
                    monotonic, the drawing may produce unexpected results. If positions is NULL,
                    then the colors are automatically spaced evenly.
        */
        SweepGradient gradient = new SweepGradient(
                mRandom.nextInt(mSize.x),
                mRandom.nextInt(mSize.y),
                getRandomColorArray(), // Colors to draw gradient
                null // Position is undefined
        );
        // Return the SweepGradient
        return gradient;
    }

    // Custom method to generate random Shader TileMode
    protected Shader.TileMode getRandomShaderTileMode(){
        /*
            Shader
                Shader is the based class for objects that return horizontal spans of colors during
                drawing. A subclass of Shader is installed in a Paint calling paint.setShader(shader).
                After that any object (other than a bitmap) that is drawn with that paint will get
                its color(s) from the shader.
        */
        Shader.TileMode mode;
        int indicator = mRandom.nextInt(3);
        if(indicator==0){
            /*
                Shader.TileMode : CLAMP
                    replicate the edge color if the shader draws outside of its original bounds
            */
            mode = Shader.TileMode.CLAMP;
        }else if(indicator==1){
            /*
                Shader.TileMode : MIRROR
                    repeat the shader's image horizontally and vertically, alternating mirror images
                    so that adjacent images always seam
            */
            mode = Shader.TileMode.MIRROR;
        }else {
            /*
                Shader.TileMode : REPEAT
                    repeat the shader's image horizontally and vertically
            */
            mode = Shader.TileMode.REPEAT;
        }
        // Return the random Shader TileMode
        return mode;
    }

    // Custom method to generate random color array
    protected int[] getRandomColorArray(){
        int length = mRandom.nextInt(16-3)+3;
        int[] colors = new int[length];
        for (int i=0; i<length;i++){
            colors[i]=getRandomHSVColor();
        }
        // Return the color array
        return colors;
    }

    // Custom method to generate random HSV color
    protected int getRandomHSVColor(){
        /*
            Hue is the variation of color
            Hue range 0 to 360

            Saturation is the depth of color
            Range is 0.0 to 1.0 float value
            1.0 is 100% solid color

            Value/Black is the lightness of color
            Range is 0.0 to 1.0 float value
            1.0 is 100% bright less of a color that means black
        */

        // Generate a random hue value between 0 to 360
        int hue = mRandom.nextInt(361);

        // We make the color depth full
        float saturation = 1.0f;

        // We make a full bright color
        float value = 1.0f;

        // We avoid color transparency
        int alpha = 255;

        // Finally, generate the color
        int color = Color.HSVToColor(alpha,new float[]{hue,saturation,value});

        // Return the color
        return color;
    }
}
More android examples