Android implements the text gradient effect and the lyrics progress Effect
To use TextView to use gradient color, we must understand the usage of LinearGradient (linear gradient.
LinearGradient parameter description
LinearGradient is also called linear rendering. LinearGradient is used to implement linear gradient effects of colors in a certain area. You can see that it is a subclass of shader from the source code.
It has two Constructors
public LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile)public LinearGradient (float x0, float y0, float x1, float y1, int[] colors, float[] positions, Shader.TileMode tile);
The x0 parameter indicates the x coordinate of the starting point of the gradient; The y0 parameter indicates the y coordinate of the starting point of the gradient; the x1 parameter indicates the x coordinate of the end point of the gradient; and The y1 parameter indicates the y coordinate of the end point of the gradient; color0 indicates the start color of the gradient. color1 indicates the end color of the gradient. the tile parameter indicates the tile mode.
There are three parameters available for Shader. TileMode: CLAMP, REPEAT, and MIRROR:
The CLAMP function is to copy the edge color to color the area out of the range if the Renderer exceeds the original boundary range.
REPEAT is used to repeatedly render the bitmap in the form of tiled horizontal and vertical
The role of MIRROR is to repeat the bitmap rendering in the form of an image either horizontally or vertically.
Simple use of LinearGradient
First, implement the horizontal gradient of the text effect:
Shader shader_horizontal= new LinearGradient(btWidth/4, 0, btWidth, 0, Color.RED, Color.GREEN, Shader.TileMode.CLAMP); tv_text_horizontal.getPaint().setShader(shader_horizontal);
Then the vertical gradient of the text is achieved:
Shader shader_vertical=new LinearGradient(0, btHeight/4, 0, btHeight, Color.RED, Color.GREEN, Shader.TileMode.CLAMP); tv_text_vertical.getPaint().setShader(shader_vertical);
Next we will achieve the text color gradient effect dynamically: <喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4NCjxwcmUgY2xhc3M9 "brush: java;"> Import android. content. context; import android. graphics. canvas; import android. graphics. linearGradient; import android. graphics. matrix; import android. graphics. paint; import android. graphics. shader; import android. util. attributeSet; import android. widget. textView;/*** Created on 2016/3/13. */public class GradientHorizontalTextView extends TextView {private LinearGradient mLinearGradient; private Matrix MGradientMatrix; // gradient matrix private Paint mPaint; // brush private int mViewWidth = 0; // textView width private int mTranslate = 0; // translation volume private boolean mAnimating = true; // animation private int delta = 15; // mobile incremental public GradientHorizontalTextView (Context ctx) {this (ctx, null);} public GradientHorizontalTextView (Context context, AttributeSet attrs) {super (context, attrs) ;}@ Override protected void onSizeChanged (int W, int h, int oldw, int oldh) {super. onSizeChanged (w, h, oldw, oldh); if (mViewWidth = 0) {mViewWidth = getMeasuredWidth (); if (mViewWidth> 0) {mPaint = getPaint (); string text = getText (). toString (); int size; if (text. length ()> 0) {size = mViewWidth * 2/text. length ();} else {size = mViewWidth;} mLinearGradient = new LinearGradient (-size, 0, 0, 0, new int [] {0x33ffffff, 0 xffffffff, 0x33fffff F}, new float [] {0, 0.5f, 1}, Shader. tileMode. CLAMP); // edge fusion mPaint. setShader (mLinearGradient); // set the gradient mGradientMatrix = new Matrix () ;}}@ Override protected void onDraw (Canvas canvas) {super. onDraw (canvas); if (mAnimating & mGradientMatrix! = Null) {float mTextWidth = getPaint (). measureText (getText (). toString (); // obtain the text width mTranslate + = delta; // by default, if (mTranslate> mTextWidth + 1 | mTranslate <1) {delta =-delta; // move to the left} mGradientMatrix. setTranslate (mTranslate, 0); mLinearGradient. setLocalMatrix (mGradientMatrix); postInvalidateDelayed (30); // refresh }}}
Achieve the progress of the lyrics
When Canvas is used as a text drawing, the FontMetrics object is used to calculate the coordinates of the position. The idea is basically the same as that of java. awt. FontMetrics.
The FontMetrics object is based on four basic coordinates:
FontMetrics. top
FontMetrics. ascent
FontMetrics. descent
FontMetrics. bottom
// FontMetrics object FontMetrics fontMetrics = textPaint. getFontMetrics (); String text = "abcdefghijklmnopqrstu"; // calculate each coordinate float baseX = 0; float baseY = 100; float topY = baseY + fontMetrics. top; float ascentY = baseY + fontMetrics. ascent; float descentY = baseY + fontMetrics. descent; float bottomY = baseY + fontMetrics. bottom;
The specific implementation code is as follows:
Import android. content. context; import android. graphics. bitmap; import android. graphics. canvas; import android. graphics. color; import android. graphics. paint; import android. graphics. porterDuff; import android. graphics. porterduxfermode; import android. graphics. rectF; import android. util. attributeSet; import android. view. view;/*** Created on 2016/3/13. */public class SongTextView extends View {private int postIndex; private Paint mPaint; private int delta = 15; private float mTextHeight; private float mTextWidth; private String mText = ""; private porterduxfermode xformode; public SongTextView (Context ctx) {this (ctx, null);} public SongTextView (Context context, attributeSet attrs) {this (context, attrs, 0);} public SongTextView (Context context, AttributeSet attrs, int defStyleAttr) {super (context, attrs, defStyleAttr ); init ();} public void init () {mPaint = new Paint (Paint. ANTI_ALIAS_FLAG); xformode = new porterduxfermode (PorterDuff. mode. SRC_IN); mPaint. setColor (Color. CYAN); mPaint. setTextSize (60366f); mPaint. setStyle (Paint. style. FILL_AND_STROKE); mPaint. setXfermode (null); mPaint. setTextAlign (Paint. align. LEFT); // specifies the exact height of the text painting. fontMetrics fontMetrics = mPaint. getFontMetrics (); mTextHeight = fontMetrics. bottom-fontMetrics.descent-fontMetrics.ascent; mTextWidth = mPaint. measureText (mText);}/*** calculate the width and height of the control */@ Override protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {final int mWidth; final int mHeight; /*** set the width */int widthMode = MeasureSpec. getMode (widthMeasureSpec); int widthSize = MeasureSpec. getSize (widthMeasureSpec); if (widthMode = MeasureSpec. EXACTLY) // match_parent, accurate mWidth = widthSize; else {// width int desireByImg = getPaddingLeft () + getPaddingRight () + getMeasuredWidth (); if (widthMode = MeasureSpec. AT_MOST) // wrap_content mWidth = Math. min (desireByImg, widthSize); else mWidth = desireByImg;}/***** set height */int heightMode = MeasureSpec. getMode (heightMeasureSpec); int heightSize = MeasureSpec. getSize (heightMeasureSpec); if (heightMode = MeasureSpec. EXACTLY) // match_parent, accurate mHeight = heightSize; else {int desire = getPaddingTop () + getPaddingBottom () + getMeasuredHeight (); if (heightMode = MeasureSpec. AT_MOST) // wrap_content mHeight = Math. min (desire, heightSize); else mHeight = desire;} setMeasuredDimension (mWidth, mHeight) ;}@ Override protected void onDraw (Canvas canvas) {super. onDraw (canvas); Bitmap srcBitmap = Bitmap. createBitmap (getMeasuredWidth (), getMeasuredHeight (), Bitmap. config. ARGB_8888); Canvas srcCanvas = new Canvas (srcBitmap); srcCanvas. drawText (mText, 0, mTextHeight, mPaint); mPaint. setXfermode (xformode); mPaint. setColor (Color. RED); RectF rectF = new RectF (0, 0, postIndex, getMeasuredHeight (); srcCanvas. drawRect (rectF, mPaint); canvas. drawBitmap (srcBitmap, 0, 0, null); init (); if (postIndex
ProgressBar
Then, the effect of playing the lyrics is achieved by two images. If you forget which one is shown, you have never thought about the implementation.
You only need to prepare two images:
I don't see two images, one as the background image and the other as the progress chart. Is it amazing? Then I put it in the ProgressBar
In addition, when the code dynamically changes progress, the progress can be changed:
ProgressBar pb1 = (ProgressBar) findViewById (R. id. pb1); // setProgressBarIndeterminateVisibility (true); progress = pb1.getProgress (); // get the initial progress timer = new Timer (); task = new TimerTask () {@ Override public void run () {progress + = 10; if (progress> 100) {progress = 0;} handler. sendEmptyMessage (0) ;}}; timer. schedule (task, 1000,300 );
Implementation and progress changes:
Handler handler=new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); pb1.setProgress(progress); }}; @Override protected void onDestroy() { super.onDestroy(); timer=null; task=null; handler.removeCallbacksAndMessages(null); }
The results are also good:
With limited capabilities, I feel like I have to write a blog for a long time. I wrote this article about the SPEED card. In fact, it is not used in the project. I have to write something after two days of rest, I think I should learn something as a slave.