There are many versions of the Android marquee, from the most basic textview, to rewriting the TextView to make the TextView remove the focus limit, as well as rewrite TextView use Scrollto method written, basic can meet the general needs. However, in the process of use, found some unexpected---sometimes do not play, the refresh thread continues but does not play, and finally on GitHub to find an animated marquee project (Project address: https://github.com/ened/ Android-marqueeview, again to the author thanked), modified some, finally OK. Don't worry about the lights anymore.
Characteristics:
1. The length of the text has a marquee effect.
2. can control the speed
Code:
Package Com.example.test_marquee;import Android.content.context;import Android.graphics.paint;import Android.text.editable;import Android.text.textwatcher;import Android.util.attributeset;import Android.util.Log; Import Android.view.gravity;import Android.view.view;import Android.view.viewgroup;import Android.view.animation.animation;import Android.view.animation.interpolator;import Android.view.animation.linearinterpolator;import Android.view.animation.translateanimation;import Android.widget.linearlayout;import Android.widget.scrollview;import android.widget.textview;/** * LinearLayout as the parent view, there must be a child textview * * Using animation to implement */public class Marqueeview extends LinearLayout {private static final int T Extview_virtual_width = 2000;/* textview default width */private static final int default_speed = 35;/* default scrolling speed the slower the scrolling */private stat IC final int default_animation_pause = 0;/* out animation with time interval to enter animation */private static final String TAG = MarqueeView.class.getSimple Name ();p rivate TextView mtextfield;/* The marquee's grandson view of TexTView */private ScrollView mscrollview;/* The sub view of the marquee Mscrollview */private Animation mmovetextout = null;/* Animations that act on TextView--go out */private Animation mmovetextin = null;/* animation that acts on TextView--enters */private Paint mpaint;private int Mspee d = default_speed;private int manimationpause = default_animation_pause;private interpolator mInterpolator = new LinearIn Terpolator ();p rivate Runnable manimationstartrunnable;/** the interval between strings */private string interval = "";p rivate string Stri Ngofitem = ""; Length of/** str+interval */private float widthofitem = 0;private float widthoftextview;private String StringOfTex TView = "";p rivate float startxofout = 0;private float endxofout = 0;private float Startxofin = 0;private float Endxofin = 0;public Marqueeview (Context context) {super (context); init (context);} Public Marqueeview (context context, AttributeSet Attrs) {Super (context, attrs); init (context);} Public Marqueeview (context context, AttributeSet attrs, int defstyle) {Super (context, attrs, defstyle); init (context);} Private void init (Context context) {//init helpermpaint = new Paint (); Mpaint.setantialias (true); Mpaint.setstrokewidth (1 ); Mpaint.setstrokecap (Paint.Cap.ROUND); minterpolator = new Linearinterpolator ();} Called when assigning a location and dimension to a child view. @Overrideprotected void OnLayout (Boolean changed, int l, int t, int r, int b) {super.onlayout (changed, L, T, R, b); LOGCAT.D (TAG, "onlayout called!" + "changed:" + changed); if (getchildcount () = = 0 | | Getchildcount () > 1) {throw new RuntimeException ("Marqueeview must has exactly one child element."); if (changed) {View v = getchildat (0); V instanceof TextView) {throw new RuntimeException ("The child view of this marqueeview must is a TextView instance."); Initview (GetContext ()); Mtextfield.settext (Mtextfield.gettext ());}} /** starts the configured marquee effect. */public void StartMarquee () {LOGCAT.D (TAG, "startmarquee called"); Starttextfieldanimation ();} Once the animation starts, the listener is responsible for the end of the animation. private void Starttextfieldanimation () {manimationstartrunnable = new Runnable () {public void Run () {mtextfield.startanimation (mmovetextout);}}; Postdelayed (manimationstartrunnable, manimationpause);} /** * Disables the animations. */public void Reset () {if (manimationstartrunnable = = null) return;removecallbacks (manimationstartrunnable); Mtextfield.clearanimation (); Mmovetextout.reset (); Mmovetextin.reset (); invalidate ();} private void Prepareanimation () {//Measurempaint.settextsize (Mtextfield.gettextsize ()); Mpaint.settypeface ( Mtextfield.gettypeface ()); float mtextwidth = Mpaint.measuretext (Mtextfield.gettext (). toString ()); Float width = Getmeasuredwidth (); startxofout =-(mtextwidth-width)% Widthofitem;endxofout =-mtextwidth + width;startXOfIn =-(MTextW Idth-width)% Widthofitem;endxofin =-mtextwidth + width;final int duration = ((int) math.abs (startxofout-endxofout) * Mspeed), if (buildconfig.debug) {log.d (TAG, "(int) Math.Abs (startxofout-endxofout):" + (int) Math.Abs (startxofout -Endxofout)); LOG.D (TAG, "mspeed:" + mspeed); LOG.D (TAG, "startxofout : "+ startxofout); LOG.D (TAG, "endxofout:" + endxofout); LOG.D (TAG, "Startxofin:" + Startxofin); LOG.D (TAG, "Endxofin:" + Endxofin); LOG.D (TAG, "duration:" + duration);} Mmovetextout = new Translateanimation (startxofout, endxofout, 0, 0); mmovetextout.setduration (duration); Mmovetextout.setinterpolator (Minterpolator); Mmovetextout.setfillafter (true); mmovetextin = new TranslateAnimation ( Startxofin, Endxofin, 0, 0); mmovetextin.setduration (duration); Mmovetextin.setstartoffset (Manimationpause); Mmovetextin.setinterpolator (Minterpolator); Mmovetextin.setfillafter (true); Mmovetextout.setanimationlistener ( New Animation.animationlistener () {public void Onanimationstart (Animation Animation) {}public void Onanimationend ( Animation Animation) {mtextfield.startanimation (mmovetextin);} public void Onanimationrepeat (Animation Animation) {}}); Mmovetextin.setanimationlistener (new Animation.animationlistener () {public void Onanimationstart (Animation Animation) {}public void OnanimAtionend (Animation Animation) {starttextfieldanimation ();} public void Onanimationrepeat (Animation Animation) {}}); /** Initialize child view */private void Initview (Context context) {//Scroll viewlayoutparams SV1LP = new Layoutparams (layoutparams.ma tch_parent,layoutparams.wrap_content); sv1lp.gravity = Gravity.center_horizontal;mscrollview = new ScrollView ( context);//Scroll View 1-text Fieldmtextfield = (TextView) getchildat (0); Removeview (Mtextfield); Mscrollview.addview ( Mtextfield, New Scrollview.layoutparams (Textview_virtual_width, layoutparams.wrap_content)); Mtextfield.addtextchangedlistener (New Textwatcher () {@Overridepublic void beforetextchanged (charsequence charsequence, int i,int i2, int i3) {} @Overridepublic void ontextchanged (charsequence charsequence, int i, int i2,int i3) {} @Overridepublic void aftertextchanged (Editable Editable) {logcat.d (TAG, "aftertextchanged called");//If the supplied string is not processed , it is processed first, otherwise the animation if (!stringoftextview.equals (editable.tostring ())) {String str = editable.tostring (); mPaint.settextsize (Mtextfield.gettextsize ()); Mpaint.settypeface (Mtextfield.gettypeface ()); StringOfItem = str + Interval;widthofitem = Mpaint.measuretext (stringofitem); Stringoftextview = Stringofitem;widthoftextview = Widthofitem;while (Widthoftextview <= 2 * getmeasuredwidth ()) {Stringoftextview + = Stringofitem;widthoftextview = Mpaint.measuretext (Stringoftextview);} LOGCAT.D (TAG, "string of TextView deal ok!###"); LOGCAT.D (TAG, "LENGTHOFLL:" + getmeasuredwidth () + "# #"); LOGCAT.D (TAG, "Lengthoftextview:" + widthoftextview+ "# # #"); LOGCAT.D (TAG, "CONTENT:" + Stringoftextview + "# # #");//Set Start Mtextfield.settext (Stringoftextview); return;} Reset ();p repareanimation (), Expandtextview ();p Ost (new Runnable () {@Overridepublic void run () {StartMarquee ();}});}); AddView (Mscrollview, SV1LP);} private void Expandtextview () {viewgroup.layoutparams LP = Mtextfield.getlayoutparams (); lp.width = (int) Widthoftextview + 5;MTEXTFIELD.SETLAYOUTPARAMS (LP);}}
Use:
<relativelayout xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:tools= "http// Schemas.android.com/tools "android:layout_width=" match_parent "android:layout_height=" Match_parent "Android:paddi ngbottom= "@dimen/activity_vertical_margin" android:paddingleft= "@dimen/activity_horizontal_margin" Android: paddingright= "@dimen/activity_horizontal_margin" android:paddingtop= "@dimen/activity_vertical_margin" tools: Context= ". Mainactivity "> <com.example.test_marquee. Marqueeview android:id= "@+id/marqueeview" android:layout_width= "Match_parent" android:layout_height= " Wrap_content "> <textview android:id=" @+id/tv_marquee "android:layout_width=" Match_pare NT "android:layout_height=" Match_parent "android:ellipsize=" End "android:singleline=" true "android:text=" Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do. " Android:textsize= "20sp "android:textstyle=" bold "/> </com.example.test_marquee. Marqueeview></relativelayout>
Demo:
http://download.csdn.net/detail/u012587637/8219987
android--the strongest marquee