1 前言

最近项目上有一个跑马灯的需求。

需求:

  • 无限滚动,可以自动切换下一条
  • 如果当前的文本超过一屏,则滚动完当前再切换下一条

第一点很简单,但是第二点就比较蛋疼了,看了网上很多轮子都没有太合适的,于是自己写了一个。 记录总结一下Android 跑马灯的实现方式,和我自定义跑马灯的思路。

源码已托管到Github:https://github.com/ieewbbwe/MarqueeView
先看下最后得效果图吧:

Android 自定义跑马灯 实现超长文本,滚动完当前在继续切换下一条_第1张图片

2 内容

2.1 需求实现

2.1.1 使用RecycleView + 自定义跑马灯

思路:1. 利用橫向RecycleView实现排列2. smoothScroll实现滑动 3. 内嵌跑马灯实现标题超长的滚动

2.1.4 ViewFlipper + 自定义跑马灯

这个实现方式是好基友告诉我的,很nice了,原理也是嵌套。
因为使用了ViwFilpper 因此想要改变滑动方向很简单。直用该进入\退出动画即可

思路:1. 外层使用ViewFlipper切分View并且滚动2. 内层使用自定义跑马灯滚动

2.1.3 自定义控件,Draw() 出滚动效果

思路1. draw出前后两笔文本2. 利用view的重绘,不断更新文本位置实现滚动

2.2 跑马灯的实现方式

2.2.1 TextView 设置Marquee

id="@+id/marqueeNormal"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginTop="8dp"        android:ellipsize="marquee"        android:focusable="true"        android:focusableInTouchMode="true"        android:marqueeRepeatLimit="marquee_forever"        android:singleLine="true"        android:text="我是普通的TextView跑马灯~跑啊跑~!" />

灰常简单,主要是这几个熟悉:

 android:ellipsize="marquee" android:marqueeRepeatLimit="marquee_forever" android:singleLine="true"

但是!!有些时候会无效!因为跑马灯要跑起来需要获取到焦点,但是由于界面复杂,有时候焦点你好控制!TextView声明只有再isFocus的时候才会走跑马灯,具体的源码自己去看了。

那么这种情况的终极解决方案是!直接继承TextView,并Override isFocused(),永久返回True。就可以了,但是还会有弹出Dialog,屏幕不亮等时候会出现问题。

最终解决如下,实测可用:

public class MarqueeText3 extends AppCompatTextView {    public MarqueeText3(Context context) {        this(context,null);    }    public MarqueeText3(Context context, AttributeSet attrs) {        super(context, attrs);        //设置单行        setSingleLine();        //设置Ellipsize        setEllipsize(TextUtils.TruncateAt.MARQUEE);        //获取焦点        setFocusable(true);        //走马灯的重复次数,-1代表无限重复        setMarqueeRepeatLimit(1);        //强制获得焦点        setFocusableInTouchMode(true);    }    @Override    public boolean isFocused() {        return true;    }    @Override    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {        if (focused) {            super.onFocusChanged(focused, direction, previouslyFocusedRect);        }    }    @Override    public void onWindowFocusChanged(boolean hasWindowFocus) {        if (hasWindowFocus)            super.onWindowFocusChanged(hasWindowFocus);    }}

参考:TextView中的跑马灯不动

2.2.2 自定义控件-使用ViewFlipper

2.2.3 自定义控件-使用Scroller 滚动

2.2.4 自定义控件-使用ScrollTo()

2.2.5 自定义控件-Canvas Draw()

3 总结

总的来说,就两种思路:

  1. 外层滚动嵌套内层滚动
  2. 绘制当前和下一个,滚动

使用手感:

使用自定义Draw的方式 可控性高,灵活,但是容易出错,计算方式比较麻烦,例子中写的还不完善;

使用嵌套的方式简单,快速,可控性不高,比如滚动时的停顿时间。

点击事件

还有一个需要注意的是,draw方法的时候,因为没有控制好点击的问题,必须再切换的时候做到迅速,不然会有一个错误情况:当第一条未滚动出屏幕,但第二条一家滑入一部分的时候,点击会出现错误,不清楚当前是属于第一条还是第二条。

参考:

https://github.com/sunfusheng/MarqueeView

https://github.com/shenjiajun53/CustomizedViews

更多相关文章

  1. Android开发——纯JAVA代码方式界面设计
  2. android 开发零起步学习笔记(九):android 控制控件的位置和大小及L
  3. 一起写一个Android图片轮播控件
  4. Android中自定义控件的步骤
  5. Android 动态增加控件
  6. Android中apk加固完善篇之内存加载dex方案实现原理(不落地方式加
  7. android 4.2.1 一种高效log打开方式
  8. [Android] 拍照、截图、保存并显示在ImageView控件中
  9. Android拼图滑块验证码控件

随机推荐

  1. 【notification】Android(安卓)中创建震
  2. android p 充拔电提示音
  3. android软件设置gps自动开启
  4. Android的SeekBar自定义样式
  5. Android(安卓)长按setOnItemLongClickLis
  6. [android studio]com.android.ide.common
  7. Android:判断手机运营商
  8. android notification 事件
  9. 两种方式使用android时间和日期控件
  10. android svg