前言:
相信很多时候开发会遇到类似于音乐歌词同步,播放到哪句歌词的哪个词时会逐渐高亮,这样的描述还是不够准确,iPhone的滑动解锁的那种效果,相信很多人都会熟悉吧。今天,我们的首要任务就是开发一个类似于这种效果的安卓控件,以便在以后的项目中直接使用,看起来高大上有木有。其实也不用害怕,需要我们分析和撰写的内容并不多,废话不多说,开始我们今天的教程吧。
正文:
在开始讲解之前,需要准备的知识点有:
public class HightLightTextView extends TextView
// 构造方法 public HightLightTextView(Context context) { this(context, null); } public HightLightTextView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public HightLightTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); }
/** * view的调用过程:构造方法->onFinishInflate->onSizeChanged->onDraw */ @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); // 获取view的宽度,初始化画笔等初始属性 if (mTextViewWidth == 0) { mTextViewWidth = getMeasuredWidth(); // 如果宽度大于0的话,则初始化 if (mTextViewWidth > 0) { // 初始化画笔 mPaint = getPaint(); // 线性渲染 mLinearGradient = new LinearGradient(-mTextViewWidth, 0, 0, 0, new int[] { 0X55FFFFFF, 0XFFFFFFFF, 0X55FFFFFF }, new float[] { 0, 0.5f, 1 }, TileMode.CLAMP); mPaint.setShader(mLinearGradient); matrix = new Matrix(); } } }
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (isAnimateOn && matrix != null) { mTranslateX += mTextViewWidth / 10; // 如果移动的距离大于两倍的宽度,则重新开始移动 if (mTranslateX > 2 * mTextViewWidth) { mTranslateX = -mTextViewWidth; } // 平移matrix matrix.setTranslate(mTranslateX, 0); // 设置线性变化的matrix mLinearGradient.setLocalMatrix(matrix); // 延迟100ms重绘 postInvalidateDelayed(100); } }
package com.beyole.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.LinearGradient; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Shader.TileMode; import android.util.AttributeSet; import android.widget.TextView; public class HightLightTextView extends TextView { // 存储view的宽度 private int mTextViewWidth = 0; // 画笔 private Paint mPaint; // 线性渲染 private LinearGradient mLinearGradient; // 存储变换的matrix private Matrix matrix; // 移动距离 private int mTranslateX = 0; // 是否开启动画 private boolean isAnimateOn = true; // 构造方法 public HightLightTextView(Context context) { this(context, null); } public HightLightTextView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public HightLightTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } /** * view的调用过程:构造方法->onFinishInflate->onSizeChanged->onDraw */ @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); // 获取view的宽度,初始化画笔等初始属性 if (mTextViewWidth == 0) { mTextViewWidth = getMeasuredWidth(); // 如果宽度大于0的话,则初始化 if (mTextViewWidth > 0) { // 初始化画笔 mPaint = getPaint(); // 线性渲染 mLinearGradient = new LinearGradient(-mTextViewWidth, 0, 0, 0, new int[] { 0X55FFFFFF, 0XFFFFFFFF, 0X55FFFFFF }, new float[] { 0, 0.5f, 1 }, TileMode.CLAMP); mPaint.setShader(mLinearGradient); matrix = new Matrix(); } } } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (isAnimateOn && matrix != null) { mTranslateX += mTextViewWidth / 10; // 如果移动的距离大于两倍的宽度,则重新开始移动 if (mTranslateX > 2 * mTextViewWidth) { mTranslateX = -mTextViewWidth; } // 平移matrix matrix.setTranslate(mTranslateX, 0); // 设置线性变化的matrix mLinearGradient.setLocalMatrix(matrix); // 延迟100ms重绘 postInvalidateDelayed(100); } } }
<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" android:background="@drawable/demo" > <com.beyole.view.HightLightTextView android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="10dip" android:textSize="22sp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="滑动解锁" /> </RelativeLayout>
下载地址:http://download.csdn.net/detail/smarticeberg/9462069
Github地址:https://github.com/xuejiawei/beyole_highlighttextview,欢迎fork or star
题外话:
android交流群:279031247(广告勿入)
新浪微博:SmartIceberg