首先android实现跑马灯,此处有三种思路,
1,android系统自带的TextView
2,自定义的view继承TextView,通过view.post延迟更新view,ondraw
3,通过自定义scrollview中包含textview,实现,具体如下
1,实现方式,代码
必须属性,少一个就不能实现
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
android:singleLine="true"
android:marqueeRepeatLimit="marquee_forever"
解释
<!-- 跑马灯效果-->
<!-- start 表示开始有三个点-->
<!-- middle 表示中间有三个点-->
<!-- end 表示结束的位置有三个点-->
android:ellipsize="marquee"
<!-- 单行显示文本-->
android:singleLine="true"
<!-- 下面两个需要同时设置才可以-->
<!-- 使控件获取到焦点针对物理键-->
android:focusable="true"
<!-- 使控件获取到焦点针对手指-->
android:focusableInTouchMode="true"
<!-- 设置文本的滚动为一直重复-->
android:marqueeRepeatLimit="marquee_forever"
注意事项:
虽然singleLine的属性已经被抛弃,但是依然不能用lines="1"来替换。
用系统自带的前提是必须此textview有焦点,此方法是只有一个textview的可以,但是当有两个跑马灯的时候,或者焦点被editText抢的时候,或者有AlertDialg就不会出现跑马灯效果,要想有效果,解决方案如下
当有两个跑马灯,需要自定义TextView,如下
package mianshi.team.com.notifactiotest.view;
import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.widget.TextView;
/**
* Created by yuanqing on 2017/2/4.
*/
public class MarqueeTextView extends TextView {
public MarqueeTextView(Context context) {
this(context, null);
}
public MarqueeTextView(Context context, AttributeSet attrs) {
super(context, attrs);
// android:singleLine="true"
setSingleLine();
// android:ellipsize="marquee"
setEllipsize(TextUtils.TruncateAt.MARQUEE);
// android:focusable="true"
setFocusable(true);
// android:focusableInTouchMode="true"
setFocusableInTouchMode(true);
// android:marqueeRepeatLimit="marquee_forever"
setMarqueeRepeatLimit(-1);
}
/**
* 解决当有两个跑马灯出现的时候,一个跑一个不动的现象
* @return
*/
@Override
public boolean isFocused() {
return true;
}
}
当有一个EditText的時候焦点也会被抢走的
解决方案效果如图
package mianshi.team.com.notifactiotest.view;
import android.content.Context;
import android.graphics.Rect;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.widget.TextView;
/**
* Created by yuanqing on 2017/2/4.
*/
public class MarqueeTextView extends TextView {
public MarqueeTextView(Context context) {
this(context, null);
}
public MarqueeTextView(Context context, AttributeSet attrs) {
super(context, attrs);
// android:singleLine="true"
setSingleLine();
// android:ellipsize="marquee"
setEllipsize(TextUtils.TruncateAt.MARQUEE);
// android:focusable="true"
setFocusable(true);
// android:focusableInTouchMode="true"
setFocusableInTouchMode(true);
// android:marqueeRepeatLimit="marquee_forever"
setMarqueeRepeatLimit(-1);
}
/**
* 解决当有两个跑马灯出现的时候,一个跑一个不动的现象
*
* @return
*/
@Override
public boolean isFocused() {
return true;
}
/**
* 解决 EditText跟跑马灯之间抢焦点的问题
*
* @param focused
* @param direction
* @param previouslyFocusedRect
*/
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
if (focused)
// 有焦点时走父类方法,焦点被抢走时,不去做操作
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
/**
* 解决AlerDilago抢焦点的问题
* @param hasWindowFocus
*/
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
if (hasWindowFocus) {
// 窗体有焦点时走父类的方法,窗体焦点消失,不去做操作
super.onWindowFocusChanged(hasWindowFocus);
}
}
}
哈哈,可以说完美解决,但是问题有出现了,跑马灯的速率怎么控制呢,采用系统的没法控制,这就需要用第二种方法了
自定义view继承TextView,
方法如下,
package mianshi.team.com.notifactiotest.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.widget.TextView;
/**
* Created by yuanqing on 2017/2/5.
*/
public class MarqueeTextView2 extends TextView implements Runnable {
private boolean isMeasure = false;
private int textWidth;
private boolean isStop = false;
private int currentScrollX;//当前滚动的位置
public MarqueeTextView2(Context context) {
super(context);
}
public MarqueeTextView2(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MarqueeTextView2(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void run() {
currentScrollX -= 1;//滚动的速率
scrollTo(currentScrollX, 0);//内容滚动
if (isStop) {
return;
}
if (getScrollX() <= -(this.getWidth())) {
scrollTo(textWidth, 0);
currentScrollX = textWidth;
return;
}
postDelayed(this, 10);
}
/**
* 开始滚动
*/
public void startScroll() {
isStop = false;
this.removeCallbacks(this);
post(this);
}
/**
* 停止滚动
*/
public void stopScroll() {
isStop = true;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (!isMeasure) {
getTextWidth();//获取字体的长度
}
}
public void getTextWidth() {
Paint paint = this.getPaint();
String str = this.getText().toString();
textWidth = (int) paint.measureText(str);
}
}
缺点是,
字体在超过一行,就有三个点移动,不显示其他的字
第三种测试,应该可以,由于最近忙着找工作,此时就不带测试了,哈