使用VerticalRollingTextView实现单行文字垂直滚动

Android代码-VerticalRollingTextView VerticalRollingTextView 竖直方向无限循环滚动文本的控件 非常轻量级,直接继承View实现 使用方法: 先在项目build.gradle中添加依赖: compile 'com.xiaosu:VerticalRollingTextView:2.0.9' 1.现在布局文件中声明 2.代码中设置数据集: mVerticalRollingView.setDataSetAdapter(new DataSetAdapter(mDataSet) { @Override protected CharSequence text(CharSequence charSequence) { return charSequence; } }); 3.开始滚动: mVerticalRollingView.run(); 4.暂停: mVerticalRollingView.stop(); 5.设置点击监听: mVerticalRollingView.setOnItemCl 立即下载
VerticalRollingTextView是一个竖直方向无限循环滚动显示单行文本的控件。非常轻量级,直接继承View实现,使用Paint绘制文本,不依赖任何第三方。

开源项目地址:
https://github.com/shubowen/VerticalRollingTextView

运行效果图:
   

一、项目使用

(1).添加项目依赖。
dependencies {
   com.xiaosu:VerticalRollingTextView:1.2.0 
}

(2).声明布局文件。
<com.xiaosu.VerticalRollingTextView
    android:id="@+id/rollingView"
    android:layout_width="match_parent"
    android:layout_height="50dp"/>

在xml中可以添加如下自定义属性。
<declare-styleable name="VerticalRollingTextView">
    <!--文字颜色-->
    <attr name="android:textColor"/>
    <!--文字大小-->
    <attr name="android:textSize"/>
    <!--滚动动画时长-->
    <attr name="android:duration"/>
    <!--两次动画之间的间隔-->
    <attr name="animInterval" format="integer"/>
</declare-styleable>

(3).添加数据集合。
List<String> textArray = ...;
verticalRollingView.setDataSetAdapter(new DataSetAdapter<String>(textArray) {
    @Override
    protected String text(String s) {
        return s;
    }
});

(4).操作控件。
// 开始滚动
verticalRollingView.run();
// 停止滚动
verticalRollingView.stop();
// 设置点击监听
verticalRollingView.setOnItemClickListener(new VerticalRollingTextView.OnItemClickListener() {
    @Override
    public void onItemClick(VerticalRollingTextView view, int index) {
        // your code
    }
});

二、源码分析

实现原理:
VerticalRollingTextView直接继承自View类,重写onDraw()方法,在onDraw()中调用Paint绘制文字。文字距离父容器顶部有一个偏移量,内部使用了一个自定义动画InternalAnimation,在动画执行过程中,不断的减小偏移量并重写绘制,达到文字向上滚动的效果。

下面是核心代码的实现。

首先是类的初始化。在构造方法中,初始化画笔,解析xml中添加的自定义属性,计算出文字的top到ascent的距离为后面使用。
public VerticalRollingTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
    
    // 初始化画笔,绘制文字使用
    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mPaint.setColor(Color.BLACK);
    mPaint.setTypeface(Typeface.DEFAULT);

    // 解析自定义属性
    parseAttrs(context, attrs);

    // 计算出top到ascent的距离,后面在onDraw()方法中调用
    Paint.FontMetricsInt metricsInt = mPaint.getFontMetricsInt();
    mTextTopToAscentOffset = metricsInt.ascent - metricsInt.top;

    mAnimation.setDuration(mDuration);
}
关于FontMetricsInt类中的top和ascent属性,可参考下图。


调用run()方法会开启动画。调用postDelayed()方法一直循环执行mRollingTask任务,在每一次任务中,调用View的startAnimation()方法启动InternalAnimation动画。
// 开启动画
public void run() {
    if (isRunning) {
        return;
    }

    isRunning = true;
    post(mRollingTask);
}

private InternalAnimation mAnimation = new InternalAnimation();

// 循环的任务
Runnable mRollingTask = new Runnable() {
    @Override
    public void run() {
        mAnimationEnded = false;
        startAnimation(mAnimation);
        postDelayed(this, mAnimInterval);
    }
};

InternalAnimation是一个自定义动画类,继承自Animation类,实现了applyTransformation()方法。在applyTransformation()中,使用参数interpolatedTime在动画执行中由0.0递增到1.0的特性,通过计算不断的减小mCurrentOffsetY的值,并调用postInvalidate()方法触发View类的onDraw()方法调用。当mCurrentOffsetY减小到endValue时,动画结束,调用animationEnd()方法。

class InternalAnimation extends Animation {
        float startValue;
        float endValue;

        // 动画执行过程中,interpolatedTime由0.0递增到1.0
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            if (mAnimationEnded)
                return;

            // 不断的修改mCurrentOffsetY的值,mCurrentOffsetY取值范围:startValue~endValue
            mCurrentOffsetY = evaluate(interpolatedTime, startValue, endValue);
            // mCurrentOffsetY的值由startValue减小到endValue时,动画结束
            if (mCurrentOffsetY == endValue) {
                animationEnd();
            }
            // 调用onDraw()方法绘制
            postInvalidate();
        }

        // 为成员变量startValue和endValue赋值
        public void updateValue(float startValue, float endValue) {
            this.startValue = startValue;
            this.endValue = endValue;
        }
    }

    // float估值器
    float evaluate(float fraction, float startValue, float endValue) {
        return startValue + fraction * (endValue - startValue);
    }

滚动文字的绘制在onDraw()方法中完成。在onDraw()中有一个初始化操作,计算偏移量,并把值添加到InternalAnimation中,这段代码只执行一次。在每一轮的动画中,onDraw()方法通过索引mCurrentIndex和mNextIndex获取需要显示的文字,调用canvas的drawText()方法将文字绘制出来。
// 绘制文本
@Override
protected void onDraw(Canvas canvas) {
    if (mDataSetAdapter == null || mDataSetAdapter.isEmpty()) {
        return;
    }

    // 获取当前需要显示的文字
    String text1 = mDataSetAdapter.getText(mCurrentIndex);
    // 获取下一个需要显示的文字
    String text2 = mDataSetAdapter.getText(mNextIndex);

    // 只需要进行一次测量
    if (mOrgOffsetY == -1) {
        mPaint.getTextBounds(text1, 0, text1.length(), bounds);
        // mOffset:文字底部到父视图顶部的距离
        mOffset = (getHeight() + bounds.height()) * 0.5f;
        // mOrgOffsetY:文字在垂直方向居中时,向上滚动的偏移量
        mOrgOffsetY = mCurrentOffsetY = mOffset - mTextTopToAscentOffset;
        // 初始化InternalAnimation中的成员变量
        mAnimation.updateValue(mOrgOffsetY, -2 * mTextTopToAscentOffset);
    }

    // 不断的绘制文本。x:始终为0不变;y:不断的减小
    canvas.drawText(text1, 0, mCurrentOffsetY, mPaint);
    canvas.drawText(text2, 0, mCurrentOffsetY + mOffset + mTextTopToAscentOffset, mPaint);
}

一轮动画执行完毕,animationEnd()方法被调用。在该方法中,增加mCurrentIndex和mNextIndex的值以获取下一次轮播的文字,并重置索引mCurrentOffsetY。
// 动画执行完成
public void animationEnd() {
    // 索引加一,取下一条数据
    mCurrentIndex++;
    // 因为文字是一直循环滚动下去的,这里使用取余数确保不会越界
    mCurrentIndex = mCurrentIndex < mDataSetAdapter.getItemCount() ? mCurrentIndex
            : mCurrentIndex % mDataSetAdapter.getItemCount();
    //计算下一个待显示文字角标
    confirmNextIndex();
    // 该轮动画完成,接下来要开始新一轮动画,重置mCurrentOffsetY变量
    mCurrentOffsetY = mOrgOffsetY;
    mAnimationEnded = true;
}

// 计算当前索引的下一条数据
private void confirmNextIndex() {
    // mNextIndex是在当前索引mCurrentIndex之后
    mNextIndex = mCurrentIndex + 1;
    // 如果mCurrentIndex已经是最后一条,mNextIndex再从0开始
    mNextIndex = mNextIndex < mDataSetAdapter.getItemCount() ? mNextIndex : 0;
}

Android文字竖直排版TextViewVertical(可横向滚动)(转) NULL 博文链接:https://hz-chenwenbiao-91.iteye.com/blog/2089851 立即下载

相关推荐

Android自定义竖排TextView实现实例

Android自定义竖排TextView实现实例 前言: 之前做联系人模块的时候遇到一个左侧索引控件,里面的字符都是竖直方向上排列的。当时这个控件是用一个图片代替的。现在想来如果索引的字符变更了,那么就得重新更换图片了,感觉很麻烦。今天通过一个自定义TextView实现类似的功能。先上效果图: 汉字和英文字符都可以竖直排列。结合联系人界面,可以将左侧的索引改成联系人的姓氏。 上代码: 测试用的Activity。 public class MainActivity extends Activity implements OnTouchListener { private Ver

android textview循环垂直滚动条,GitHub - shubowen/VerticalRollingTextView: 竖直方向无限循环滚动显示文本的控件...

VerticalRollingTextView竖直方向无限循环滚动文本的控件非常轻量级,直接继承View实现使用方法:先在项目build.gradle中添加依赖:compile 'com.xiaosu:VerticalRollingTextView:2.0.9'1.现在布局文件中声明android:layout_width="match_parent"android:layout_height="...

weixin_33814002的博客 427

Windows系统下LaTeX环境搭建与编辑器配置全攻略

本文详细介绍了在Windows系统下搭建LaTeX环境的完整流程,包括TeX Live的安装、TeXStudio编辑器的配置优化以及常见问题排查。特别针对中文用户推荐使用清华镜像源加速下载,并提供了XeLaTeX编译器配置、中文支持等实用技巧,帮助用户快速上手LaTeX文档编写。

weixin_42554408的博客 449

滚动文本视图 RollingTextView - 带来创新的文本动画体验

滚动文本视图 RollingTextView - 带来创新的文本动画体验 RollingTextAndroid TextView with rolling animation项目地址:https://gitcode.com/gh_mirrors/ro/RollingText 1、项目介绍 RollingTextView 是一个强大的 Android 开源库,它为你的应用添加了富有创意的文本滚动动...

gitblog_00030的博客 529

保姆级教程:用YOLOv8n模型在RKNN和Horizon平台完成目标检测(附C++部署代码与性能实测)

本文提供了一份详尽的YOLOv8n模型在RKNN和Horizon平台上的部署指南,涵盖环境配置、模型优化、跨平台适配及性能调优。通过实战案例和C++部署代码,帮助开发者在嵌入式设备上高效实现目标检测,显著提升推理性能。

weixin_42659194的博客 468

华为OD机试真题2025双机位A卷 Java&Go 实现【采购订单】

在一个采购系统中,采购申请(PR)需要经过审批后才能生成采购订单(PO)。每个PR包含商品的单价(假设相同商品的单价一定是一样的)及数量信息。系统要求对商品进行分类处理:单价高于100元的商品需要单独处理,单价低于或等于100元的相同商品可以合并到同一采购订单PO中。针对单价低于100的小额订单,如果量大可以打折购买。

MISAYAONE的博客 1257

垂直滚动的Textview 类似小喇叭通知

首先将自定义控件导入到项目中 public class AutoVerticalScrollTextView extends TextSwitcher implements ViewSwitcher.ViewFactory { private Context mContext; //mInUp,mOutUp分别构成向下翻页的进出动画 private Rotat

默丶 807

嵌入式AI实战:基于RK3588部署YOLOv11并集成OpenCV实现实时推理(全流程详解)

本文详细介绍了在RK3588芯片上部署YOLOv11目标检测模型的全流程,包括环境搭建、模型转换和实时推理实现。主要内容为:1)通过YOLOv11官方工具将PyTorch模型转为ONNX格式;2)使用RKNN Toolkit2将ONNX模型转换为适配RK3588的RKNN格式;3)在RK3588上结合OpenCV实现实时视频推理功能。教程提供了完整的代码示例和详细步骤说明,帮助开发者快速在边缘设备上部署目标检测模型,实现AI视觉应用的落地。

LXY_LOVE36的博客 212

推荐文章:滚动文字视图 - RollingTextView,为你的应用增添活力

在移动开发的世界里,创新的用户体验设计永远是吸引用户的法宝之一。今天,我们要向您介绍一款独特且功能强大的Android组件——**RollingTextView**,它不仅能够提升您的应用视觉吸引力,还能通过其独特的文字滚动效果,为信息展示带来全新维度。 ## 项目介绍 RollingTextView是一个精心设计的开源项目,它基于TextView扩展,赋予了文本一种生动的滚动效果。想象一下,...

gitblog_00106的博客 545

CAN总线数据采集与分析

在CAN总线数据采集中,数据采集是指从CAN网络中获取数据,并将其存储在本地或远程数据库中。数据源:明确数据源,如CAN总线、CANoe/CANalyzer工具等。数据格式:确定数据格式,如CAN消息、信号值、环境变量等。数据存储:选择数据存储方式,如本地文件、数据库、云存储等。在CAN总线数据分析中,数据分析是指对采集到的数据进行处理和分析,以提取有用的信息。数据处理:对采集到的数据进行处理,如滤波、去噪、归一化等。数据分析:对处理后的数据进行分析,如统计分析、趋势分析、故障诊断等。数据可视化。

闲人编程的博客 4042

ros入门(八)---TF坐标转换

TF(TransForm),就是坐标转换,包括了位置和姿态两个方面的变换。

weixin_51157015的博客 3388

Android 上下滚动字幕实现

首先values文件夹下添加或创建attrs文件,如下:   &lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;resources&gt; &lt;!--//垂直滚动字幕--&gt; &lt;declare-styleable name="VerticalRollingTextView"&gt; &amp

meixi_android的博客 4280

2026 Claude Code 标准化前端UI SKILL——Frontend Design

是 Anthropic 官方开源的技能包,在 Claude 官方插件站中排名第一,超过 52k 的下载量。场景推荐方案快速体验批量安装官方 Skills深度设计策略叠加完整打磨流程集成终端跑claude一句话总结:Frontend Design 不是给 AI 加新能力,而是给 AI 加审美标准。它让 AI 从“能画”变成“会设计”——先想清楚风格,再动手写代码。

十年老程序猿,AI 疯狂研究专家,前沿硬核知识分享 3603

Android 上下滚动字幕实现(1)

testEntity1.setTitle(“谷歌。testEntity.setTitle(“百度。

2501_90328376的博客 254

30天Python入门(第一天:Python入门)

30天带你入门Python,这是第一天

Science prince的博客 582

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

上下滚动文字自定义控件

创建自定义控件VerticalRollingTextView

zyh0709的博客 560

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

2018任务清单

1.MVVM  参考2.RxJava,RxAndroid3.React Native4.Hybird5.Kotlin6.Python7.JavaEE

fcjmlyd的博客 310

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Android 实现竖排文本(垂直方向显示)

在 Android 应用程序中显示垂直文本可以通过多种方法实现,具体取决于项目的复杂性和要求。以下介绍在 Android 中显示垂直文本的几种方法。init();init();init();= text &&!init();init();@Overridei++) {这些方法应该涵盖了 Android 中显示竖排文本的大部分场景。自定义视图方法提供了最大的灵活性,而旋转TextView是最简单、最快的方法。

2034

自定义VerticalTextView

最近做需求,网上找不到链接,于是自己做一个简陋版的VerticalTextView GitHub下载链接 git@github.com:13540634851/PreferenceDemo.git 效果图 注意: 由于是自定义View,TextView’的属性在这里不管用 只有3个方法可用 设置显示的字符串, public void setText(String text) ; 设置对齐方式 ...

淡定的人的博客 1161

自定义TextView实现竖排文本

最近有竖排文本的需求,整理了一些实现方式,最终自定义TextView绘制文本方式满足需求

qq_22509515的专栏 3304

探索创新文本显示方式:VerticalTextView

探索创新文本显示方式:VerticalTextView 在数字化阅读的时代,我们每天都会接触各种各样的UI元素,其中最基础也最重要的就是文本视图。然而,传统的水平滚动的TextView可能已经不能满足所有设计需求。为此,让我们一起深入了解一个独特的开源项目——,它将文本以垂直方向显示,为界面设计带来新的可能性。 项目简介 VerticalTextView是由开发者@yifei8创建的一个Andro...

gitblog_00078的博客 594

android自定义View-垂直滚动的TextView

自定义垂直滚动的TextView,主要是用来学习Scroller的使用。关于ScrollTextView的实现,可以看下面的介绍和源码。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 3

专注Android开发 844

android滚动列表VerticalRollingTextView

项目中需要滚动展示通知消息,之前用的是VerticalRollingTextView的1.2.0,但该版本不支持多行滚动,而2.0版本的支持多行滚动展示,目前我使用的版本是2.0.9。1.2.0与2.0.9版本之间有些差异,路径有略微区别,一下我做出两版的代码作参考。以上是设置了通知消息的滚动时间、停留时间还有设置了通知消息的点击监听事件。这一版我是在maven中心下载下放在项目里用的,直接引用地址下载异常。app:itemCount="2" 设置显示数据的行数。以上为两个版本的简单实现。

weixin_31172555的博客 186

Java 数字滚动_RollingTextView:带有数字滚动动画的Android TextView

RollingTextView Featureseasy to use, API is similar to TextView, and the setText method can be animated with up and down rollingsupport XML to set up common properties such as android:textSize/ andro...

weixin_33988332的博客 452

android垂直滚动显示,Android 上下滚动字幕实现

首先values文件夹下添加或创建attrs文件,如下:1、自定义上下滚动字幕textview、VerticalRollingTextView/*** 作者:created by meixi* 邮箱:13164716840@163.com* 日期:2018/8/30 10*/public class VerticalRollingTextView extends View {DataSetAdap...

weixin_39952937的博客 681
上一篇: 使用VerticalBannerView实现垂直轮播广告(仿淘宝头条)
下一篇: 设计模式之模板方法模式
ruancoder
博客等级 码龄10年 42粉丝 66原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值