今天公司项目让实现一个跑马灯的效果,因为有用户反映总是忘记还款截至时间,于是就要求做一个单条文字横向滚动的效果,用于提示用户。
GitHub上找了几个跑马灯的库,本以为可以实现自己想要的效果,不过这个库真心不错,推荐给大家:
1.sunfusheng/MarqueeView 这是扩展了 ViewFlipper
实现的。
2.gongwen/MarqueeViewLibrary 这也是扩展了ViewFlipper
控件实现的
这两个库虽然文字过长时都可以滚动,但是文字显示不全,超出部分被省略掉了
下面总结下我实现过程中遇到的坑
1.首先我是在一个小demo里面对TextView设置下面的属性就可以实现跑马灯效果,代码如下:
<TextView
android:layout_width="120dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:ellipsize="marquee"
android:singleLine="true"
android:focusable="true"
android:marqueeRepeatLimit="marquee_forever"
android:focusableInTouchMode="true"
android:scrollHorizontally="true"
android:text="abcdefghijklmnopqrstuvwxyz.0123456789"
/>
但是我写到项目里面并没有出现滚动效果
最后发现原来焦点被其他控件抢走了
解决的方法我们可以通过自定义TextView来实现:重写 isFocused(),返回为ture
public class MarqueeView extends TextView {
public MarqueeView(Context context) {
super(context);
}
public MarqueeView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public MarqueeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean isFocused() {
return true;
}
}
2.如果这时,布局文件中有两个跑马灯和一个EditText的话,第一个走马灯就会停止。
这是因为EditText获取了焦点,解决方案,重写父类的 onFocusChanged 方法即可
我们在自定义的MarqueeView 中重写onFocusChanged
/*
* 用于EditText抢注焦点的问题
* */
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
if (focused) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
}
3.如果我们弹出一个对话框的话,会发现,弹出对话框后,跑马灯效果就停止了,原因是Dialog抢了焦点,解决方案就是重写下onWindowFocusChanged方案
/*
* Window与Window间焦点发生改变时的回调
* */
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
if (hasWindowFocus)
super.onWindowFocusChanged(hasWindowFocus);
}
至此,我们的Android跑马灯效果已经可以完美的运行了。
不过唯一不足的是,文字过短不会有滚动效果