Robinhood团队谈字符滚动控件Ticker的实现

原文:Hello, Ticker 

1-jCa23drqVob_PRr1Cv0Kug.gif

用户体验至上是Robinhood(罗宾侠)工程师团队的最高原则之一。我们相信一个直观的用户体验可以帮助我们区别于其它app并且帮助我们从一个传统金融巨头转向一个移动端优先的经纪商。我们非常感激的是设计驱动开发的努力被消费者和业界所认同,并且也让iOS 和  Androidapp在它们被发布的头一年就获得了两个设计奖项。但是,我们并未停止。面对新的标准与期望,我们仍不断的寻找改进与重构app的方法。我们寻找新的开源库、框架和工具,因为我们认为自己写的代码越少,维护的越少,今后我们就越灵活。我们听取客户的建议和反馈来改进app。与此同时我们还要维护自己设定的高标准与用户的期望。

最后,团队把焦点放在建造高性能的移动端架构与UI模块上面,这样我们的app就能在所有设备上流畅高效的运行。其中一个模块就是ticker text模块,以华尔街上常见的证券报价机命名。当我们在建立安卓上的ticker模块时,我们遇到了一些新的需求:

  1. 高性能:动画不会导致任何卡顿,尤其是在滚动和滑动的时候。

  2. 低内存消耗:比如:不能使用多个View。

  3. 可插入:核心逻辑应该被合理的封装,这样UI模块可以在不同的地方重用。

  4. 简单,可扩展的API:只需定义文字的渲染和动画方式。

  5.  尽可能低的Android SDK version需求。

本着以上的几点,我们开发出了ticker module的第一个版本并运用到了我们的安卓初始公开版本。在经过了一些磕碰和迭代之后,我们很高兴宣布把Ticker贡献到开源社区!


什么是Ticker?

Ticker是一个显示滚动文字的UI控件。你可以想象一下里程表切换到下一个数字时是如何滚动的,Ticker所做的事情就与之类似。Ticker处理了字符切换与数字增长(比如从9999到10000的动画)的动画。

你可以通过定义一个有序的字符数组来指定如何呈现动画。Ticker中每个字符的显示都是通过这个数组来控制,它规定了如何从一个开始字符过渡到目标字符。比如,如果你只使用一个基本的ASCII字符列表,那么当要实现A到Z的时候,实际是A->B->...Z。字符的顺序不能倒过来,所以当动画要从Z到A的时候,其实是‘Z’ -> ‘Y’ -> … -> ‘A’。

让我们重温一下上面的需求并谈谈时如何实现它们的。

高性能低内存

我们决定继承最基本的View类,所有的效果都直接在canvas上绘制出来。这样做的好处是高度灵活,对内存分配完全可控,而且使用本地的绘制操作可以最大程度减小对性能的影响。我们尽可能的预先分配和计算好每一个transition,这样在绘制路径的时候唯一要做的就是绘制操作了。 

API易插入,简单可扩展的API

不管是通过XML还是代码,Ticker都很易定义和使用,支持自定义(当前支持自定义文字颜色和大小,插值器,以及动画时间)。目前公开的api还非常有限,随着新需求的出现,我们将尽力公开更多的方法和自定义渠道。

要定义一个TickerView,把它放在XML布局中:

<com.robinhood.ticker.TickerView
    android:id=”@+id/tickerView”
    android:layout_width=”wrap_content”
    android:layout_height=”wrap_content”
    app:ticker_textColor=”?colorPrimary”
    app:ticker_textSize=”16sp” />

设置插值器,设置控制动画行为的的字符列表就算完成了!

final TickerView tickerView = findViewById(R.id.tickerView);
tickerView.setAnimationInterpolator(new OvershootInterpolator());
tickerView.setCharacterList(TickerUtils.getDefaultNumberList());
tickerView.setText(“1234”);
…
tickerView.setText(“4321”);

尽可能低的Android SDK版本

Ticker需要API12及以上,因为它使用了framework的动画库。运行ICS及以上的安卓设备大约占98%,所以这应该不算一个issue。


Explore more

Ticker现在可以在 Github上获取了,关于如何制作一个更好的API以及应该支持哪些其它的用例请告诉我!