TextView, and modeled after the source code, mainly to cancel the focus and select the judge, also do not rely on the width of the text.
Import java.lang.ref.WeakReference;
Import Android.content.Context;
Import Android.graphics.Canvas;
Import Android.os.Handler;
Import Android.os.Message;
Import Android.util.AttributeSet;
Import Android.widget.TextView;
public class Marqueetextview extends TextView {private Marquee mmarquee;
Public Marqueetextview (context, AttributeSet attrs) {Super (context, attrs); Marqueetextview (context, AttributeSet attrs, int defstyle) {Super (context, Attrs, defst
YLE);
Public Marqueetextview {Super (context);
public void StartMarquee () {StartMarquee (-1); public void StartMarquee (int repeatlimit) {if (Mmarquee = null) Mmarquee = new Marquee (th
IS);
Mmarquee.start (Repeatlimit); public void StopMarquee () {if (Mmarquee!= null &&!mmarquee.isstopped ()) {Mmarqu Ee.stop(); } public void Togglemarquee () {if (Mmarquee = null | | mmarquee.isstopped ()) Startmarq
Uee ();
else StopMarquee (); } @Override protected void OnDraw (Canvas Canvas) {if mmarquee!= null && mmarquee.isrunning
()) {final float dx =-mmarquee.getscroll ();
Canvas.translate (getlayoutdirection () = = Layout_direction_rtl?-DX: +dx, 0.0f);
} super.ondraw (canvas); @SuppressWarnings ("unused") private static final class Marquee extends Handler {//Todo:add an op
tion to configure this private static final float Marquee_delta_max = 0.07f;
private static final int marquee_delay = 0;//1200;
private static final int marquee_restart_delay = 1200;
private static final int marquee_resolution = 1000/30;
private static final int marquee_pixels_per_second = 30; PrivAte static final byte marquee_stopped = 0x0;
private static final byte marquee_starting = 0x1;
private static final byte marquee_running = 0x2;
private static final int message_start = 0x1;
private static final int message_tick = 0x2;
private static final int message_restart = 0x3;
Private final weakreference<textview> Mview;
Private byte mstatus = marquee_stopped;
Private final float mscrollunit;
private float Mmaxscroll;
private float Mmaxfadescroll;
private float Mghoststart;
private float Mghostoffset;
private float mfadestop;
private int mrepeatlimit;
private float Mscroll; Marquee (TextView v) {final float density = V.getcontext (). Getresources (). Getdisplaymetri
CS (). density;
Mscrollunit = (Marquee_pixels_per_second * density)/marquee_resolution; MView = new Weakreference<textview> (v); @Override public void Handlemessage (msg) {switch (msg.what) {case
Message_start:mstatus = marquee_running;
Tick ();
Break
Case Message_tick:tick ();
Break
Case Message_restart:if (Mstatus = = marquee_running) {if (mrepeatlimit >= 0) {
mrepeatlimit--;
Start (Mrepeatlimit);
} break;
} void Tick () {if (mstatus!= marquee_running) {return;
} removemessages (Message_tick);
Final TextView TextView = Mview.get (); && (textview.isfocused () | | textview.isselected ()) if (TextView!= null) {mScroll + = Mscrollunit;
if (Mscroll > Mmaxscroll) {mscroll = Mmaxscroll;
Sendemptymessagedelayed (Message_restart, Marquee_restart_delay);
else {sendemptymessagedelayed (Message_tick, marquee_resolution);
} textview.invalidate ();
} void Stop () {mstatus = marquee_stopped;
Removemessages (Message_start);
Removemessages (Message_restart);
Removemessages (Message_tick);
Resetscroll ();
private void Resetscroll () {mscroll = 0.0f;
Final TextView TextView = Mview.get ();
if (TextView!= null) {textview.invalidate ();
} void Start (int repeatlimit) {if (Repeatlimit = 0) {stop ();
Return } mrepeatlimit = Repeatlimit;
Final TextView TextView = Mview.get ();
if (TextView!= null && textview.getlayout ()!= null) {mstatus = marquee_starting;
Mscroll = 0.0f;
Final int textWidth = Textview.getwidth ()-Textview.getcompoundpaddingleft ()
-Textview.getcompoundpaddingright ();
Final float linewidth = Textview.getlayout (). Getlinewidth (0);
Final float gap = textwidth/3.0f;
Mghoststart = Linewidth-textwidth + gap;
Mmaxscroll = Mghoststart + textWidth;
Mghostoffset = LineWidth + gap;
Mfadestop = linewidth + textwidth/6.0f;
Mmaxfadescroll = Mghoststart + linewidth + linewidth;
Textview.invalidate ();
Sendemptymessagedelayed (Message_start, Marquee_delay); }} FLOat Getghostoffset () {return mghostoffset;
Float Getscroll () {return mscroll;
Float Getmaxfadescroll () {return mmaxfadescroll;
Boolean Shoulddrawleftfade () {return mscroll <= mfadestop; Boolean shoulddrawghost () {return mstatus = = marquee_running && mscroll > Mghoststa
Rt
Boolean isrunning () {return mstatus = = marquee_running;
Boolean isstopped () {return mstatus = = marquee_stopped; }
}
}
See more highlights of this column: http://www.bianceng.cnhttp://www.bianceng.cn/OS/extra/
Code Description:
1, the elimination of focus and selected judgment
2, the delay of 1200 to 0, the immediate implementation of the effect of the valley lights.
3, the core code is directly from the TextView copy out.
End
This is mainly to provide a solution to the problem of ideas, the actual use of the corresponding changes need to be made.
Author: cnblogs Peasant Uncle