• Stars
    star
    117
  • Rank 296,062 (Top 6 %)
  • Language
    Java
  • Created over 6 years ago
  • Updated over 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

自定义跑马灯效果

前言

最近公司接到小需求--「可以滚动的提示」,其实就是跑马灯。这让我想到了大学时专业物联网,当时学的单片机入门教程就是跑马灯,很是亲切。其实就是灯(或文字)按照某个方向循环滚动。

Android 原生的跑马灯

其实,Android中的TextView自带跑马灯效果,只需要通过简单的配置,就可以完成滚动的效果。

XML中进行配置

<TextView
    android:id="@+id/test"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:ellipsize="marquee"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:marqueeRepeatLimit="marquee_forever"
    android:scrollHorizontally="true"
    android:singleLine="true"
    android:text="我是跑马灯,我是跑马灯,我是跑马灯,我是跑马灯,我是跑马灯,我是跑马"
    android:textSize="28sp" />

可以看到需要很多的属性配置,了解一下每个属性的含义:

  • android:ellipsize="marquee" 设置为跑马灯效果
  • android:focusable="true" 获取焦点
  • android:focusableInTouchMode="true" touch 时获取焦点
  • android:marqueeRepeatLimit="marquee_forever" 设置重复次数
  • android:scrollHorizontally="true" 设置为水平滚动
  • android:singleLine="true" 单行显示

按照上面的配置,正常情况下是可以运转的,但是用到项目中的时候,会发现很多bug和不足之处。

比如,偶尔突然不滚动了,具体的原因是没有获取到焦点。我觉得这是原生跑马灯最坑的一点,必须获取到焦点才能正常运行。

当然解决方式也有,第一种,通过主动获取焦点的方式,即调用view.setFocusable(true)。还有一种就是重写TextViewisFocused()方法,强制让他获取焦点。

@Override
public boolean isFocused() {
    return true;
}

就算这样,在遇到复杂的界面还是会遇到问题,要么焦点会被断断续续的被抢夺,导致卡顿,要么不符合UI提出的滚动速度要求。

自定义跑马灯

鉴于这个背景,通过Scroller完成自定义的跑马灯,代码已上传至GitHub上:MarqueeTextView

先看一下整体的效果:

MarqueeTextView

如果想直接使用,在根build.gradle配置:

allprojects {
	repositories {
		...
		maven { url 'https://jitpack.io' }
	}
}

app下的build.gradle添加依赖

dependencies {
	compile 'com.github.xiaweizi:MarqueeTextView:1.0'
}

最后在XML直接使用即可:

   <com.xiaweizi.marquee.MarqueeTextView
        android:id="@+id/marquee1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="@string/string1"
        android:textColor="#ff0000"
        android:textSize="18sp"
        app:scroll_first_delay="0"
        app:scroll_interval="2000"
        app:scroll_mode="mode_forever" />

具有一下功能:

  • 控制滚动时间
  • 控制滚动延迟
  • 控制滚动模式
  • 生命周期可以自己控制
    • 暂停
    • 继续
    • 重新开始
    • 停止

实现原理

通过Scroller控制器来控制整个View的滚动,那什么是Scroller,做个简单的介绍。

Scroller内部封装了滚动的操作,通过构造函数中传入插值器。可以控制起始位置和整个滚动的时间,并且通过computeScrollOffset()得到滚动动作是否结束。

最核心的方法有两个:

  1. startScroll

     /**
      * @param startX 水平方向滚动的偏移值,以像素为单位。
      * @param startY 垂直方向滚动的偏移值,以像素为单位
      * @param dx     水平方向滚动的距离
      * @param dy     垂直方向滚动的距离
      * @param duration 滚动持续的时间,以毫秒为单位
      */
     public void startScroll (int startX, int startY, int dx, int dy, int duration) {
         ...
     } 
    
  2. computeScrollOffset

     /**
      * @return 返回动画是否结束
      */
     public boolean computeScrollOffset (){
         ...
     }
    

注释已经很清楚了,那么接下来讲一下滚动的大概实现。

首先,要算出从初始位置开始滚动,到结束的距离,其实就是文字的长度。

/**
 * 计算滚动的距离
 * @return 滚动的距离
 */
private int calculateScrollingLen() {
    TextPaint tp = getPaint();
    Rect rect = new Rect();
    String strTxt = getText().toString();
    tp.getTextBounds(strTxt, 0, strTxt.length(), rect);
    return rect.width();
}

其次,调用startScroll方法进行滚动,注意的是需要调用invalidate方法,才会有效果。

最后一个问题就是,滚动结束后继续滚动。Scroller在滚动的时候,会不断回调ViewcomputeScroll方法,于是就可以在这个方法里进行判断,如果结束了,就重新开始。

到此一个简单的跑马灯效果就实现了,当然如果还想添加别的需要,只要搞懂其原理,这些都不是问题。

More Repositories

1

SimplicityWeather

一款简约风格的 flutter 天气项目,提供实时、多日、24 小时、台风路径以及生活指数等服务,支持定位、删除、搜索等操作。
Dart
442
star
2

AndroidToolsExample

Android 中 tools 命名的使用案例
Java
237
star
3

QNews_Kotlin

趣闻-Kotlin版,我的毕设项目
Java
164
star
4

flutter_weather_bg

A rich and cool weather dynamic background plug-in
Dart
162
star
5

jsoupJianshuDemo

使用jsoup爬虫获取简书首页的小demo
Java
52
star
6

RoundCornersView

利用 Glide 实现图片的圆角效果
Java
40
star
7

DownloadLoadingView

仿 IOS 桌面图标下载 view
Java
33
star
8

TransitionDemo

Transition 相关的 demo
Java
32
star
9

QNews_React_Native

趣闻-ReactNative 版
JavaScript
30
star
10

MaterialDesign

集中了大量得 MaterialDesign 设计风格得控件
Java
28
star
11

ScollDemo

交互的 Demo
Java
26
star
12

ShortcutsDemo

Android 7.1 之后推出的 shortcuts 使用 Demo
Java
19
star
13

AndroidMD

Material Design 在 Android 中的应用
Kotlin
16
star
14

QNews_we_chat

趣闻-小程序版
JavaScript
16
star
15

EvaluationCardView

客服评价view
Java
8
star
16

BankPickerView

银行选择器
Java
5
star
17

QQChat

基于环信的简单通信的实现
Java
5
star
18

ImageCache

一个新手的三级缓存的自学笔记
Java
5
star
19

ThreadPoolDemo

线程池相关
Java
5
star
20

QNews_Android

趣闻-Android版
Java
4
star
21

PythonTest

个人的 Python 学习笔记
Python
3
star
22

LockScreenDemo

锁屏页面展示功能实现
Java
2
star
23

BackupBlog

我的博客备份
Stylus
2
star
24

QNews_Flutter

趣闻-Flutter 版
Dart
2
star
25

xiaweizi.github.io

我的个人博客
HTML
1
star
26

FloatingWindow

悬浮窗
Java
1
star
27

FlutterDemo

我的 flutter 项目测试 demo
Dart
1
star
28

DataStructureAlgorithms

数据结构与算法练习
Java
1
star
29

CustomViewPractice5

自定义 View 练习 5
Java
1
star
30

TransView

传输炫酷动画
Java
1
star
31

ThreadProject

多线程联系代码
Java
1
star
32

XWZWebView

Java
1
star