Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Marquee Set Speed

Tags:

android

I Am using a marquee to show the text in one of my Activitys. My question is it possible to speed up the rate of the marquee so it scrolls along the screen faster. Below is my XML and Java.

TextView et2 = (TextView) findViewById(R.id.noneednum);
    et2.setEllipsize(TruncateAt.MARQUEE);    
    et2.setText("");
    if (num.size() > 0) {
        for (String str : num) {
            et2.append(str + "    ");
        }
    }
    et2.setSelected(true);
}

And XML:

<TextView
    android:id="@+id/noneednum"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:ellipsize="marquee"
    android:fadingEdge="horizontal"
    android:gravity="center_vertical|center_horizontal"
    android:lines="1"
    android:marqueeRepeatLimit="marquee_forever"
    android:scrollHorizontally="true"
    android:singleLine="true"
    android:text="Large Text"
    android:textColor="#fff"
    android:textSize="140dp" />
like image 623
Matt Avatar asked Jan 23 '12 11:01

Matt


2 Answers

You have to create a custom class for scrolling the text:

ScrollTextView.java

public class ScrollTextView extends TextView {

     // scrolling feature
     private Scroller mSlr;

     // milliseconds for a round of scrolling
     private int mRndDuration = 10000;

     // the X offset when paused
     private int mXPaused = 0;

     // whether it's being paused
     private boolean mPaused = true;

     /*
     * constructor
     */
     public ScrollTextView(Context context) {
         this(context, null);
         // customize the TextView
         setSingleLine();
         setEllipsize(null);
         setVisibility(INVISIBLE);
     }

     /*
     * constructor
     */
     public ScrollTextView(Context context, AttributeSet attrs) {
         this(context, attrs, android.R.attr.textViewStyle);
         // customize the TextView
         setSingleLine();
         setEllipsize(null);
         setVisibility(INVISIBLE);
     }

     /*
     * constructor
     */
     public ScrollTextView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
         // customize the TextView
         setSingleLine();
         setEllipsize(null);
         setVisibility(INVISIBLE);
     }

     /**
     * begin to scroll the text from the original position
     */
     public void startScroll() {
         // begin from the very right side
         mXPaused = -1 * getWidth();
         // assume it's paused
         mPaused = true;
         resumeScroll();
     }

     /**
     * resume the scroll from the pausing point
     */
     public void resumeScroll() {

         if (!mPaused) return;

         // Do not know why it would not scroll sometimes
         // if setHorizontallyScrolling is called in constructor.
         setHorizontallyScrolling(true);

         // use LinearInterpolator for steady scrolling
         mSlr = new Scroller(this.getContext(), new LinearInterpolator());
         setScroller(mSlr);

         int scrollingLen = calculateScrollingLen();
         int distance = scrollingLen - (getWidth() + mXPaused);
         int duration = (new Double(mRndDuration * distance * 1.00000
         / scrollingLen)).intValue();

         setVisibility(VISIBLE);
         mSlr.startScroll(mXPaused, 0, distance, 0, duration);
         invalidate();
         mPaused = false;
     }

     /**
     * calculate the scrolling length of the text in pixel
     *
     * @return the scrolling length in pixels
     */
     private int calculateScrollingLen() {
         TextPaint tp = getPaint();
         Rect rect = new Rect();
         String strTxt = getText().toString();
         tp.getTextBounds(strTxt, 0, strTxt.length(), rect);
         int scrollingLen = rect.width() + getWidth();
         rect = null;
         return scrollingLen;
     }

     /**
     * pause scrolling the text
     */
     public void pauseScroll() {
         if (null == mSlr) return;

         if (mPaused)
         return;

         mPaused = true;

         // abortAnimation sets the current X to be the final X,
         // and sets isFinished to be true
         // so current position shall be saved
         mXPaused = mSlr.getCurrX();

         mSlr.abortAnimation();
     }

     @Override
     /*
     * override the computeScroll to restart scrolling when finished so as that
     * the text is scrolled forever
     */
     public void computeScroll() {
         super.computeScroll();

         if (null == mSlr) return;

         if (mSlr.isFinished() && (!mPaused)) {
           this.startScroll();
         }
     }

     public int getRndDuration() {
       return mRndDuration;
     }

     public void setRndDuration(int duration) {
       this.mRndDuration = duration;
     }

     public boolean isPaused() {
       return mPaused;
     }
}

In your layout write like this:

<yourpackagename.ScrollTextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/scrolltext" />

In your activity write like this:

ScrollTextView scrolltext=(ScrollTextView) findViewById(R.id.scrolltext);
scrolltext.setText(yourscrollingtext);
scrolltext.setTextColor(Color.BLACK);
scrolltext.startScroll();

If you want to increase the scrolling speed then reduce the value of :

private int mRndDuration = 10000;//reduce the value of mRndDuration to increase scrolling speed
like image 179
Ramakrishna Avatar answered Oct 19 '22 20:10

Ramakrishna


Above code fails if the TextView is an instance of AppCompatTextView. Below code works is it is AppCompatTextView. Tested in Marshmallow.

public static void setMarqueeSpeed(TextView tv, float speed) {
    if (tv != null) {
        try {
            Field f = null;
            if (tv instanceof AppCompatTextView) {
                f = tv.getClass().getSuperclass().getDeclaredField("mMarquee");
            } else {
                f = tv.getClass().getDeclaredField("mMarquee");
            }
            if (f != null) {
                f.setAccessible(true);
                Object marquee = f.get(tv);
                if (marquee != null) {
                    String scrollSpeedFieldName = "mScrollUnit";
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        scrollSpeedFieldName = "mPixelsPerSecond";
                    }
                    Field mf = marquee.getClass().getDeclaredField(scrollSpeedFieldName);
                    mf.setAccessible(true);
                    mf.setFloat(marquee, speed);
                }
            } else {
                Logger.e("Marquee", "mMarquee object is null.");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
like image 32
Hitesh Gupta Avatar answered Oct 19 '22 20:10

Hitesh Gupta