Android跑马灯效果实现的三种方式
1、使用系统默认的跑马灯效果
实现方法:
(1)在xml文件加入一个TextView,并设置属性如下,其中红色的部分是最关键部分
android:id="@+id/textView_showmsg_circle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:textColor="#ff0000"
android:singleLine="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:background="#ffffff"
android:focusable="true"
android:focusableInTouchMode="true"
android:scrollHorizontally="true"
/>
(2)通过设置xml中的属性,该TextView已经具备了跑马灯的效果。但是,此种情况下,只有当TextView获取到焦点时,才能出现跑马灯效果,一旦丢失焦点,跑马灯效果不再,控件从开始显示一定宽度的字符。其效果如下图例所示。
主程序代码:
finalTextViewtvCircle = (TextView)
findViewById(R.id.textView_showmsg_circle);
tvCircle.setText("2.2.1. 紧急通知类消息紧急通知类型的消息主要指恶劣天气警报或政府部门授权下发的紧急事件通知。");
2、自定义类,派生于TextView,重新实现函数,使其在丢失焦点的情况下也可更新
(1)自定义派生类,派生于TextView。实现接口函数,使其在丢失焦点的情况下,返回true,从而实现在丢失焦点的情况下也可以实现跑马灯效果。实现代码如下:
publicclassMarqueenTextView1extendsTextView {
} public MarqueenTextView1(Context context, AttributeSetattrs) { } @Override protectedvoidonFocusChanged(boolean focused, int direction, } @Override publicvoidonWindowFocusChanged(booleanhasWindowFocus) { } @Override publicbooleanisFocused() { returntrue;//始终返回true } if(hasWindowFocus) super.onWindowFocusChanged(hasWindowFocus); if(focused) super.onFocusChanged(focused, direction, previouslyFocusedRect); super(context, attrs); // TODO Auto-generated constructor stub RectpreviouslyFocusedRect) {
(2)在xml文件中,使用该自定义的派生控件即可,定义的关键部分与第一种方法类似。代码如下:
<com.example.marqueetextview.MarqueenTextView1
android:id="@+id/textView_showmsg_circle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:textColor="#ff0000"
android:singleLine="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:background="#ffffff"
android:focusable="true"
android:focusableInTouchMode="true"
android:scrollHorizontally="true"
/>
(3)在主函数中调用该控件,并且调用父类函数赋值,可以显示跑马灯效果,且可以在丢失焦点情况下继续滚动。
final com.example.marqueetextview.MarqueenTextView1 tvCircle =
(com.example.marqueetextview.MarqueenTextView1) findViewById(R.id.textView_showmsg_circle);
tvCircle.setText("2.2.1. 紧急通知类消息紧急通知类型的消息主要指恶劣天气警报或政府部门授权下发的紧急事件通知。");
效果图如下:
(4)上述方法虽然可以实现在丢失焦点的情况下,继续滚动显示消息的跑马灯效果。但是,却不能灵活的控制滚动速度和滚动次数。
3、自定义类,派生于TextView,并实现Runnable接口
(1)自定义类,派生于TextView,并且实现Runnable接口。原理是通过线程控制画布,滚动显示消息。通过控制线程启停,可以控制显示的次数;通过控制一次滚动的位置和滚动的时间间隔,实现滚动速度的控制。定义类如下:
publicclassMarqueeTextViewextendsTextViewimplements Runnable {
privatestaticfinal String TAG = "MarqueeTextView"; privateintcircleTimes = 1; privateinthasCircled = 0; privateintcurrentScrollPos = 0; privateintcircleSpeed = 1; privateinttextWidth = 0; privatebooleanisMeasured = false; private
Handler handler;
privatebooleanflag = false; publicMarqueeTextView(Context context, AttributeSetattrs) { super(context, attrs); // TODO Auto-generated constructor stub this.removeCallbacks(this); post(this);
handler = new Handler();
handler.postDelayed(this, 300); // //
}
// @Override
//
//
//
// }
//
// @Override
// public void onWindowFocusChanged(booleanhasWindowFocus) { //
//
// }
//
// @Override
// public booleanisFocused() {
//
// }
//
@Override protectedvoidonDraw(Canvas canvas) { } @Override publicvoidsetVisibility(int visibility){ //二次进入时初始化成员变量 flag = false; isMeasured = false; this.hasCircled = 0; super.setVisibility(visibility); super.onDraw(canvas); if(!isMeasured){ } getTextWidth(); isMeasured = true; return true; if(hasWindowFocus) super.onWindowFocusChanged(hasWindowFocus); if(focused) super.onFocusChanged(focused, direction, previouslyFocusedRect);