Android自定义view-打造酷炫的字体滑动高亮控件
2016-03-15 14:07
706 查看
前言:
相信很多时候开发会遇到类似于音乐歌词同步,播放到哪句歌词的哪个词时会逐渐高亮,这样的描述还是不够准确,iPhone的滑动解锁的那种效果,相信很多人都会熟悉吧。今天,我们的首要任务就是开发一个类似于这种效果的安卓控件,以便在以后的项目中直接使用,看起来高大上有木有。其实也不用害怕,需要我们分析和撰写的内容并不多,废话不多说,开始我们今天的教程吧。
正文:
在开始讲解之前,需要准备的知识点有:
必要的安卓基础
安卓view 的执行流程
Android画笔的LinearGradient线性渲染
好了,其实对于以上知识点不了解也没有关系,要是都了解了,就没有必要写这篇文章了。
问题一:为什么要有必要的安卓基础呢?
如果对继承,重写组件没有必要的了解,这篇文章是看不下去的。
问题二:安卓的view执行流程是什么呢?
执行构造方法
onFinishInflate
onSizeChanged
onDraw
....
问题三:LinearGradient的线性渲染需要了解哪些内容呢?
LinearGradient有两个构造函数:
public LinearGradient(float x0, float y0, float x1, float y1, int[] colors, float[] positions,Shader.TileMode tile)
参数:
float x0: 渐变起始点x坐标
float y0:渐变起始点y坐标
float x1:渐变结束点x坐标
float y1:渐变结束点y坐标
int[] colors:颜色 的int 数组
float[] positions: 相对位置的颜色数组,可为null, 若为null,可为null,颜色沿渐变线均匀分布
Shader.TileMode tile: 渲染器平铺模式
public LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1,Shader.TileMode tile)
float x0: 渐变起始点x坐标
float y0:渐变起始点y坐标
float x1:渐变结束点x坐标
float y1:渐变结束点y坐标
int color0: 起始渐变色
int color1: 结束渐变色
Shader.TileMode tile: 渲染器平铺模式
Shader.TileMode有3种参数可供选择,分别为CLAMP、REPEAT和MIRROR:
CLAMP的作用是如果渲染器超出原始边界范围,则会复制边缘颜色对超出范围的区域进行着色
REPEAT的作用是在横向和纵向上以平铺的形式重复渲染位图
MIRROR的作用是在横向和纵向上以镜像的方式重复渲染位图
知识准备已经完成了,开始动手撸代码了。
Step1:继承TextView
Step2:重写三个构造方法,当然根据需要,重写一个两个参数的构造方法也行。我复写三个是为了以后能够使用自定义属性。
Step3:在onSizeChanged方法中初始化参数。
这里有个细节,就是画笔的获取,我们不是new出来的,而是通过getPaint()获取父类中的画笔,所以接下来的onDraw中没有用到paint,不要怀疑代码有问题哦。
至于LinearGradient的每个参数对照我们的知识准备应该不难理解各种参数对应的意思。那么,还剩下一个问题,这里的mTextViewWidth为什么是负的,喏,其实我们的matrix的移动是从-mTextViewWidth<=translate<=mTextViewWidth,可能还是不能理解吧。我们到下面画个图解释一下就清楚了。
Step4:在onDraw中绘制view
其实我们移动的就是蓝色的matrix,移动了两倍的textview之后,再重置matrix,然后就postInvalidateDelayed绘制我们的view。okay了,看到这里应该很熟悉怎么去写这样的一个效果了吧。如果你觉得滑动慢,改变一些重绘的时间,如果你觉得颜色需要改变,那就设置对外的接口,或者直接修改view里的颜色即可,至于扩展,留给大家扩展了。
这里贴上view 的全部代码以及如何使用:
HightLightTextView.java
activity_main.xml:
好了,教程到此为止结束了。
下载地址:http://download.csdn.net/detail/smarticeberg/9462069
Github地址:https://github.com/xuejiawei/beyole_highlighttextview,欢迎fork
or star
题外话:
android交流群:279031247(广告勿入)
新浪微博:SmartIceberg
相信很多时候开发会遇到类似于音乐歌词同步,播放到哪句歌词的哪个词时会逐渐高亮,这样的描述还是不够准确,iPhone的滑动解锁的那种效果,相信很多人都会熟悉吧。今天,我们的首要任务就是开发一个类似于这种效果的安卓控件,以便在以后的项目中直接使用,看起来高大上有木有。其实也不用害怕,需要我们分析和撰写的内容并不多,废话不多说,开始我们今天的教程吧。
正文:
在开始讲解之前,需要准备的知识点有:
必要的安卓基础
安卓view 的执行流程
Android画笔的LinearGradient线性渲染
好了,其实对于以上知识点不了解也没有关系,要是都了解了,就没有必要写这篇文章了。
问题一:为什么要有必要的安卓基础呢?
如果对继承,重写组件没有必要的了解,这篇文章是看不下去的。
问题二:安卓的view执行流程是什么呢?
执行构造方法
onFinishInflate
onSizeChanged
onDraw
....
问题三:LinearGradient的线性渲染需要了解哪些内容呢?
LinearGradient有两个构造函数:
public LinearGradient(float x0, float y0, float x1, float y1, int[] colors, float[] positions,Shader.TileMode tile)
参数:
float x0: 渐变起始点x坐标
float y0:渐变起始点y坐标
float x1:渐变结束点x坐标
float y1:渐变结束点y坐标
int[] colors:颜色 的int 数组
float[] positions: 相对位置的颜色数组,可为null, 若为null,可为null,颜色沿渐变线均匀分布
Shader.TileMode tile: 渲染器平铺模式
public LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1,Shader.TileMode tile)
float x0: 渐变起始点x坐标
float y0:渐变起始点y坐标
float x1:渐变结束点x坐标
float y1:渐变结束点y坐标
int color0: 起始渐变色
int color1: 结束渐变色
Shader.TileMode tile: 渲染器平铺模式
Shader.TileMode有3种参数可供选择,分别为CLAMP、REPEAT和MIRROR:
CLAMP的作用是如果渲染器超出原始边界范围,则会复制边缘颜色对超出范围的区域进行着色
REPEAT的作用是在横向和纵向上以平铺的形式重复渲染位图
MIRROR的作用是在横向和纵向上以镜像的方式重复渲染位图
知识准备已经完成了,开始动手撸代码了。
Step1:继承TextView
public class HightLightTextView extends TextView
Step2:重写三个构造方法,当然根据需要,重写一个两个参数的构造方法也行。我复写三个是为了以后能够使用自定义属性。
// 构造方法 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); }
Step3:在onSizeChanged方法中初始化参数。
/** * 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(); } } }
这里有个细节,就是画笔的获取,我们不是new出来的,而是通过getPaint()获取父类中的画笔,所以接下来的onDraw中没有用到paint,不要怀疑代码有问题哦。
至于LinearGradient的每个参数对照我们的知识准备应该不难理解各种参数对应的意思。那么,还剩下一个问题,这里的mTextViewWidth为什么是负的,喏,其实我们的matrix的移动是从-mTextViewWidth<=translate<=mTextViewWidth,可能还是不能理解吧。我们到下面画个图解释一下就清楚了。
Step4:在onDraw中绘制view
@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); } }
其实我们移动的就是蓝色的matrix,移动了两倍的textview之后,再重置matrix,然后就postInvalidateDelayed绘制我们的view。okay了,看到这里应该很熟悉怎么去写这样的一个效果了吧。如果你觉得滑动慢,改变一些重绘的时间,如果你觉得颜色需要改变,那就设置对外的接口,或者直接修改view里的颜色即可,至于扩展,留给大家扩展了。
这里贴上view 的全部代码以及如何使用:
HightLightTextView.java
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); } }
}
activity_main.xml:
<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
相关文章推荐
- Android APK 打包
- Gradle构建Android项目
- Android 开发百度地图之五 路线规划
- Android SDK Manager无法更新列表
- (4.5.1.2)Open an existing Android Studio project和Import Non-Android Studio project图解
- android ImageView实现上面圆角下面直角(自定义view实现)
- 个人学习android的基本知识记录
- 第十一章 Android 内核驱动——Alarm
- Android系统框架
- Android Studio 增加函数注释模板
- android判断service是否活着
- android sdk
- Android开发中无处不在的设计模式——观察者模式
- Android ListView异步加载图片乱序问题,原因分析及解决方案
- Android基础-DatePickerAndTimePicker用法
- Android 数据之Json解析
- Android系统自带样式(android:theme)详解
- [置顶] Android官方开发文档Training系列课程中文版:目录
- Android中Spanner的使用
- Android注销功能