Android 自定义跑马灯 实现超长文本,滚动完当前在继续切换下一条
1 前言
最近项目上有一个跑马灯的需求。
需求:
- 无限滚动,可以自动切换下一条
- 如果当前的文本超过一屏,则滚动完当前再切换下一条
第一点很简单,但是第二点就比较蛋疼了,看了网上很多轮子都没有太合适的,于是自己写了一个。 记录总结一下Android 跑马灯的实现方式,和我自定义跑马灯的思路。
源码已托管到Github:https://github.com/ieewbbwe/MarqueeView
先看下最后得效果图吧:
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 总结
总的来说,就两种思路:
- 外层滚动嵌套内层滚动
- 绘制当前和下一个,滚动
使用手感:
使用自定义Draw的方式 可控性高,灵活,但是容易出错,计算方式比较麻烦,例子中写的还不完善;
使用嵌套的方式简单,快速,可控性不高,比如滚动时的停顿时间。
点击事件
还有一个需要注意的是,draw方法的时候,因为没有控制好点击的问题,必须再切换的时候做到迅速,不然会有一个错误情况:当第一条未滚动出屏幕,但第二条一家滑入一部分的时候,点击会出现错误,不清楚当前是属于第一条还是第二条。
参考:
https://github.com/sunfusheng/MarqueeView
https://github.com/shenjiajun53/CustomizedViews
更多相关文章
- Android开发——纯JAVA代码方式界面设计
- android 开发零起步学习笔记(九):android 控制控件的位置和大小及L
- 一起写一个Android图片轮播控件
- Android中自定义控件的步骤
- Android 动态增加控件
- Android中apk加固完善篇之内存加载dex方案实现原理(不落地方式加
- android 4.2.1 一种高效log打开方式
- [Android] 拍照、截图、保存并显示在ImageView控件中
- Android拼图滑块验证码控件