首先看看效果图(录制的gif有点卡,真实的效果还是很流畅的)

实现思路

通过上面的gif图可以得出结论,其实它就是同时绘制两条文本信息,然后通过动画不断的改变两条文本信息距离顶部的高度,以此来实现滚动的效果。

具体实现

首先定义一些要用到的属性

动画开始延迟时间

动画重复延迟时间

单个动画的执行时间

接下来解析属性值

private void init(Context context, AttributeSet attrs) {

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MarqueeViewStyle);

mTextColor = typedArray.getColor(R.styleable.MarqueeViewStyle_textColor, Color.BLACK);

mTextSize = typedArray.getDimensionPixelSize(R.styleable.MarqueeViewStyle_textSize, 45);

mPaddingLeft = typedArray.getDimensionPixelSize(R.styleable.MarqueeViewStyle_paddingLeft, 15);

mPaddingTop = mPaddingBottom = typedArray.getDimensionPixelSize(R.styleable.MarqueeViewStyle_paddingTopBottom, 25);

mPaddingTop = typedArray.getDimensionPixelSize(R.styleable.MarqueeViewStyle_paddingTop, mPaddingTop);

mPaddingBottom = typedArray.getDimensionPixelSize(R.styleable.MarqueeViewStyle_paddingBottom, mPaddingBottom);

itemAnimationTime = typedArray.getInteger(R.styleable.MarqueeViewStyle_itemAnimationTime, 1000);

reRepeatDelayTime = typedArray.getInteger(R.styleable.MarqueeViewStyle_reRepeatDelayTime, 1000);

startDelayTime = typedArray.getInteger(R.styleable.MarqueeViewStyle_startDelayTime, 500);

typedArray.recycle();

mPaint = new Paint();

mPaint.setAntiAlias(true);

mPaint.setTextSize(mTextSize);

mPaint.setColor(mTextColor);

mPaint.setTextAlign(Paint.Align.LEFT);}

重写onMeasure方法

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

if(mTextArray == null || mTextArray.length == 0) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

} else {

int width = MeasureSpec.getSize(widthMeasureSpec);

int height = MeasureSpec.getSize(heightMeasureSpec);

ViewGroup.LayoutParams lp = getLayoutParams();

setMeasuredDimension(getViewWidth(lp, width), getViewHeight(lp, height));

}

}

数据为空时调用父类的方法,设置数据以后根据不同的布局计算宽高。

设置数据

public void setTextArray(String[] textArray) {

if(textArray == null || textArray.length <= 1) return;

mTextArray = textArray;

initTextRect();

setTextCurrentOrNextStatus(0, 1, true);

startAnimation();}

initTextRect()方法是计算出单个文本的高度和数组中最大文本的宽度,文本的高度用来计算绘制文本时的位置,文本的最大宽度在onMeasure()方法的时候会用到。

setTextCurrentOrNextStatus()方法设置当前的position,文本以及下一个position,文本。还有文本距离顶部的初始化高度。

startAnimation() 方法 开始执行动画。

动画实现

private void startAnimation() {

va = ValueAnimator.ofFloat(0, 1);

va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

mProgress = (float) animation.getAnimatedValue();

. int moveOffset = (int) (mTextMoveOffset * mProgress);

mCurrentTextMoveMarginTop = mCurrentTextInitMarginTop - moveOffset;

mNextTextMoveMarginTop = mNextTextInitMarginTop - moveOffset;

postInvalidate();

}

});

va.addListener(new AnimatorListenerAdapter() {

@Override

public void onAnimationRepeat(Animator animation) {

va.pause();

setTextCurrentOrNextStatus(mNextTextPosition, mNextTextPosition + 1, false);

handler.postDelayed(new Runnable() {

@Override

public void run() {

va.resume();

}

}, reRepeatDelayTime);

}

});

va.setRepeatCount(-1);

va.setDuration(itemAnimationTime);

va.setStartDelay(startDelayTime);

va.start();

}

va.setRepeatCount(-1);设置动画无限重复

onAnimationUpdate()方法得到动画执行的进度,计算出text距离顶部的距离,调用postInvalidate()方法刷新界面。

onAnimationRepeat()方法,通过handler延迟reRepeatDelayTime时间,再重新执行动画。

绘制

protected void onDraw(Canvas canvas) {

if(mTextArray == null || mTextArray.length == 0) {

super.onDraw(canvas);

} else {

canvas.drawText(mCurrentText, mPaddingLeft, mCurrentTextMoveMarginTop, mPaint);

canvas.drawText(mNextText, mPaddingLeft, mNextTextMoveMarginTop, mPaint);

}

}

总结

到这里所有的代码已经分析完毕,其实实现这个效果还有很多种方法,通过继承ViewGroup等等都可以实现,大家有兴趣可以自己尝试。希望本文的内容对大家的学习或者工作能有所帮助,如果有疑问大家可以留言交流。

android跑马灯效果横向,Android自定义View实现纵向跑马灯效果详解相关推荐

  1. 安卓自定义view系列之paint画笔类详解

    /** * Paint类介绍 * * Paint即画笔,在绘图过程中起到了极其重要的作用,画笔主要保存了颜色, * 样式等绘制信息,指定了如何绘制文本和图形,画笔对象有很多设置方法, * 大体上可以分 ...

  2. android自定义拱形,Android自定义View实现圆弧进度的效果

    前言 Android开发中,常常自定义View实现自己想要的效果,当然自定义View也是Android开发中比较难的部分,涉及到的知识有Canvas(画布),Paint(画笔)等,自定义控件分为三种: ...

  3. Android仿IOS解锁密码界面-自定义view系列(6)

    Android仿IOS解锁密码界面-自定义view系列 功能简介 主要实现步骤-具体内容看github项目里的代码 xml相关属性设置 Android Studio 代码 Android技术生活交流 ...

  4. Android开发之制作圆形头像自定义View,直接引用工具类,加快开发速度。带有源代码学习

    作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985 QQ986945193 博客园主页:http://www.cnblogs.com/mcxiaobing ...

  5. Android开发之制作圆形头像自定义View,直接引用工具类,加快开发速度。带有源代码学习...

    作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985 QQ986945193 博客园主页:http://www.cnblogs.com/mcxiaobing ...

  6. Android绘图机制(二)——自定义View绘制形, 圆形, 三角形, 扇形, 椭圆, 曲线,文字和图片的坐标讲解

    Android绘图机制(二)--自定义View绘制形, 圆形, 三角形, 扇形, 椭圆, 曲线,文字和图片的坐标讲解 我们要想画好一些炫酷的View,首先我们得知道怎么去画一些基础的图案,比如矩形,圆 ...

  7. Android安卓仿IOS音量调节-自定义view系列(4)

    Android安卓仿IOS音量调节-自定义view系列 功能简介 主要实现步骤 xml相关属性设置 java代码 Android技术生活交流 更多其他页面-自定义View-实用功能合集:点击查看 Gi ...

  8. Android绘图机制(三)——自定义View的实现方式以及半弧圆新控件

    Android绘图机制(三)--自定义View的三种实现方式以及实战项目操作 在Android绘图机制(一)--自定义View的基础属性和方法 里说过,实现自定义View有三种方式,分别是 1.对现有 ...

  9. android生命周期_Android开发 View的生命周期结合代码详解

    咱们以TextView控件为例: /** * Created by SunshineBoy on 2020/9/23. */ public class TestTextView extends and ...

最新文章

  1. C++所提供的类模板应用(堆栈)
  2. 北京尚学堂|程序员励志名言
  3. JVM常用的参数配置
  4. jbpm 和 drools_Drools和jBPM KIE A​​pps平台
  5. UTF-8的CSV文件中文乱码问题解决办法
  6. 是不是每一个型号的单片机都要学一遍
  7. linux 添加删除用户
  8. Docker第一章:安装及初始化配置
  9. 华为大数据平台使用pyhive连接hive的方法(Kerberos验证)
  10. 刘汝佳--WERTY
  11. C语言编程-对数字进行分类
  12. Tcp三次握手、四次握手、数据传输
  13. python 实现otu表水平转化
  14. java学习--类与对象
  15. 高精度1------高精度乘法
  16. oppo手机设置wifi代理和charles证书
  17. AutoCAD 2007创建块
  18. 记一个ie兼容apos
  19. 微盟股价逆变的背后: 经济寒冬已至,SaaS产业如何破局?
  20. 【车牌识别】基于matlab GUI阈值分割车牌识别(带面板)【含Matlab源码 721期】

热门文章

  1. 猿创征文|我的Go成长之路道阻且长
  2. 自动换刀主轴与手动换刀主轴优缺点对比
  3. Anaconda 安装及验证是否安装成功
  4. Unity中获取一个物体下所有的子物体的方法
  5. 隐藏输入法图标的方法
  6. 计算机专业试讲10分钟教案,10分钟试讲教案模板.doc
  7. 复习|typedef什么意思,用法,作用
  8. HTML网页设计:六、列表
  9. 华为AR路由器无法上网解决办法
  10. StringUtils常用方法(五)