Giter VIP home page Giter VIP logo

marqueetextview's Introduction

前言

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

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方法,于是就可以在这个方法里进行判断,如果结束了,就重新开始。

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

marqueetextview's People

Contributors

xiaweizi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

marqueetextview's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.