In Android you need to do some gradient effects for the rendered UI. To achieve these effects we need to understand the use of Android gradients. So we need to know about a very important class, Shader.
Shader
There are five classes that inherit from Shader:
BitmapShader: Bitmap image rendering. LinearGradient: Linear rendering. SweepGradient: Gradient rendering/gradient rendering. RadialGradient: Loop render. ComposeShader: Render a ComposeShader
1. BitmapShader: bitmap image rendering ####
BitmapShader only works on Bitmap, which is used to render and color the drawn graph. The constructor needs to pass in the image’s pull-up mode TileMode. At the same time, setting the effect of different tilemodes is also the focus of BitmapShader!
mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR);
Copy the code
To use it, first paint. SetShader (), then canvas.draw();
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setShader(mBitmapShader);
canvas.drawRect(0, 0, 800, 800, mPaint);
}
Copy the code
Here, a picture is used to fill a square with side length of 800, and the length and width are stretched in the same way. CLAMP — is the last pixel stretched across.
CLAMP
MIRROR – is the horizontal and vertical areas of the continuous flip MIRROR tiling.
MIRROR
REPEAT – similar to computer wallpaper, with insufficient horizontal and vertical placement.
REPEAT
2. LinearGradient: Linear rendering ####
/** 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)
Copy the code
X0: the x-coordinate of the rendering starting point y0: the y-coordinate of the rendering starting point x1: the x-coordinate of the rendering ending point y1: the y-coordinate of the rendering ending point Colors: the set of colors to render. Positions: ratio of color to render, and if null is passed, render evenly. Tile: Stretch mode, similar to BitmaopShaper. Other constructors are not covered here, and the meanings of the parameters passed in are easy to understand
MLinearGradient = new that LinearGradient (0500500500, new int [] {Color. RED, the Color BLUE, Color, GRAY, Color, GREEN}, null, Shader.TileMode.MIRROR);Copy the code
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setShader(mLinearGradient);
canvas.drawRect(0, 0, 800, 800, mPaint);
}
Copy the code
Effect picture:.
LinearGradient
3. SweepGradient: Gradient rendering ####
/** * A subclass of Shader that draws a sweep gradient around a center point. * * @param cx The x-coordinate of the center * @param cy The y-coordinate of the center * @param colors The colors to be distributed between around the center. * There must be at least 2 colors in the array. * @param positions May be NULL. The relative position of * each Corresponding color in the colors array, beginning * with 0 and ending with 1.0. the drawing may produce unexpected results. * If positions is NULL, then the colors are automatically * spaced evenly. */ public SweepGradient(float cx, float cy, int colors[], float positions[])Copy the code
Cx: Renders the x-coordinate of the center of the circle. Cy: Renders the y coordinate of the center point of the circle. Colors: Set of colors for rendering. Positions: The ratio of color to render, and if null is passed, evenly render. Other constructors are not covered here, and the meanings of the parameters passed in are easy to understand
mSweepGradient = new SweepGradient(250, 250, new int[]{Color.GREEN, Color.YELLOW, Color.RED}, null);
Copy the code
To use it, first paint. SetShader (), then canvas.draw();
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setShader(mSweepGradient);
canvas.drawCircle(250, 250, 250, mPaint);
}
Copy the code
Effect:
SweepGradient
4, RadialGradient: Ring render ####
/** Create a shader that draws a radial gradient given the center and radius. @param centerX The x-coordinate of the center of the radius @param centerY The y-coordinate of the center of the radius @param radius Must be positive. The radius of the circle for this gradient. @param colors The colors to be distributed between the center and edge of the Circle @param stops May be <code> NULL </code>. Valid values are between <code>0.0f</code> and <code>1.0f</code>. The relative position of each corresponding color in the colors array. If <code>null</code>, colors are distributed evenly between the center and edge of the circle. @param tileMode The Shader tiling mode */ public RadialGradient(float centerX, float centerY, float radius, @NonNull int colors[], @Nullable float stops[], @NonNull TileMode tileMode)Copy the code
CenterX: Renders the x-coordinate of the center point of the circle. CenterY: Render the y coordinates of the center point of the circle. Radius: Render the radius of the circle. Colors: Set of colors for rendering. Stops: the proportion of the color of the stops; if null is passed, the stops will be uniformly drawn. TileMode: Stretch mode, similar to BitmaopShaper. Other constructors are not covered here, and the meanings of the parameters passed in are easy to understand
mRadialGradient = new RadialGradient(250, 250, 250, new int[]{Color.RED, Color.GREEN, Color.BLACK}, null, Shader.TileMode.CLAMP);
Copy the code
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setShader(mRadialGradient);
canvas.drawCircle(250, 250, 250, mPaint);
}
Copy the code
Effect:
RadialGradient
5, ComposeShader ####
ComposeShader adds the two renders together. Why two? Because:
/** Create a new compose shader, given shaders A, B, and a combining mode. When the mode is applied, it will be given the result from shader A as its "dst", and the result from shader B as its "src". @param shaderA The colors from this shader are seen as the "dst" by the mode @param shaderB The colors from this shader are seen as the "src" by the mode @param mode The mode that combines the colors from the two shaders. If mode is null, then SRC_OVER is assumed. */ public ComposeShader(Shader shaderA, Shader shaderB, Xfermode mode) { mType = TYPE_XFERMODE; mShaderA = shaderA; mShaderB = shaderB; mXferMode = mode; init(nativeCreate1(shaderA.getNativeInstance(), shaderB.getNativeInstance(), (mode ! = null) ? mode.native_instance : 0)); } /** Create a new compose shader, given shaders A, B, and a combining PorterDuff mode. When the mode is applied, it will be given the result from shader A as its "dst", and the result from shader B as its "src". @param shaderA The colors from this shader are seen as the "dst" by the mode @param shaderB The colors from this shader are seen as the "src" by the mode @param mode The PorterDuff mode that combines the colors from the two shaders. */ public ComposeShader(Shader shaderA, Shader shaderB, PorterDuff.Mode mode) { mType = TYPE_PORTERDUFFMODE; mShaderA = shaderA; mShaderB = shaderB; mPorterDuffMode = mode; init(nativeCreate2(shaderA.getNativeInstance(), shaderB.getNativeInstance(), mode.nativeInt)); }Copy the code
Its constructor can only pass two render effects. (However, is it possible to pass the ComposeShader constructor into a ComposeShader for multiple render effects?) A third parameter of the constructor is set stacking mode: blog.csdn.net/t12x3456/ar…
public class ComposeShaderTestView extends View { private ComposeShader composeShader; Private BitmapShader mBitmapShader; private Bitmap mBitmap; Private LinearGradient mLinearGradient; private Paint mPaint; public ComposeShaderTestView(Context context) { this(context, null); } public ComposeShaderTestView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public ComposeShaderTestView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.hy2); mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); mLinearGradient = new LinearGradient(0, mBitmap.getHeight(), mBitmap.getWidth(), mBitmap.getHeight(), new int[]{Color.RED, Color.BLUE, Color.GRAY, Color.GREEN}, null, Shader.TileMode.MIRROR); ComposeShader = new composeShader (mBitmapShader, mLinearGradient, porterduff.mode.multiply); mPaint = new Paint(); mPaint.setAntiAlias(true); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setShader(composeShader); canvas.drawRect(0, 0, mBitmap.getWidth(), mBitmap.getHeight(), mPaint); }}Copy the code
Linear rendering and bitmap rendering are superimposed here.
ComposeShader
If the use of the basic understanding of the Shader, then look at the see Shader instance effect: www.jianshu.com/p/3ded93e3b…
Code address: github.com/AxeChen/Gra…