SoFunction
Updated on 2025-03-08

Android Custom TextView Marquee Effect

The marquee lights that come with Android are not easy to control, and the conditions must be met to be effective, and the speed is not controlled. There is an article in my blog that uses the marquee effect that comes with Android, but based on different usage effects, I found a better method online here. I followed some of the author's methods, but added better extension functions to share with you. There is a realization of control to the left and right directions.

1. First of all, a simple layout

<LinearLayout xmlns:andro 
  xmlns:tools="/tools" 
  android:layout_width="fill_parent" 
  android:layout_height="fill_parent" 
  android:orientation="vertical" > 
 
 
  <Button 
    android: 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:onClick="start" 
    android:text="start" /> 
 
 
  <Button 
    android: 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:onClick="stop" 
    android:text="stop" /> 
 
 
  <Button 
    android: 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:onClick="startFromHead" 
    android:text="Reset" /> 
 
 
  < 
    android: 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:background="#339320" 
    android:ellipsize="marquee" 
    android:singleLine="true" 
    android:text="Scrolling effect, no matter how many words" 
 
    android:ellipsize = "marquee" // The marquee effect, if the number of words does not exceed, it will not move, if it exceeds, it will roll    android:textColor="#000000" 
    android:textSize="20dp" > 
  </> 
 
 
</LinearLayout> 

2. Custom scrolling method

import ; 
import ; 
import ; 
import ; 
import ; 
 
 
public class MarqueeText extends TextView implements Runnable { 
private int currentScrollX; // The current scrolling positionprivate boolean isStop = false; 
private int textWidth; 
private boolean isMeasure = false; 
 
 
public MarqueeText(Context context) { 
super(context); 
} 
 
 
public MarqueeText(Context context, AttributeSet attrs) { 
super(context, attrs); 
} 
 
 
public MarqueeText(Context context, AttributeSet attrs, int defStyle) { 
super(context, attrs, defStyle); 
} 
 
 
@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
// TODO Auto-generated method stub 
(widthMeasureSpec, heightMeasureSpec); 
currentScrollX = (); 
} 
 
 
protected void onDraw(Canvas canvas) { 
(canvas); 
if (!isMeasure) { 
getTextWidth();// The text width only needs to be obtained onceisMeasure = true; 
} 
} 
 
 
private void getTextWidth() { 
Paint paint = (); 
String str = ().toString(); 
textWidth = (int) (str); 
} 
 
 
@Override 
/*
 * public void run() { currentScrollX-=2;//Scroll speed.+ sign indicates to the left-
 * scrollTo(currentScrollX,0); if(isStop){ return; }
 * if(getScrollX()<=-(())){ scrollTo(textWidth,0);
 * currentScrollX=textWidth; } postDelayed(this, 5); }
 */ 
public void run() { 
currentScrollX += 2;// Scroll speed.+ sign indicates to the left-scrollTo(currentScrollX, 0); 
if (isStop) { 
return; 
} 
if (getScrollX() &gt;= (textWidth)) { 
currentScrollX = -(());// The current location} 
postDelayed(this, 1); 
} 
/*(public void run() {
 
 
 // currentScrollX += 3;// Scroll speed.+ sign indicates to the left-
 // scrollTo(currentScrollX, 0);
 
 
 if (textWidth>()) {
 currentScrollX += 3;// Scroll speed.+ sign indicates to the left-
 scrollTo(currentScrollX, 0);
 }
 if (getScrollX() >= (textWidth)) {
 // scrollTo((),0);
 currentScrollX = -(());// Current location
 }
 postDelayed(this, 5);
 }) What is achieved here is the effect of no ellipsis.  If the text does not exceed the length of the box, it will not roll. If it exceeds the length of the box, it will not roll. 
 
// Start scrollingpublic void startScroll() { 
isStop = false; 
(this); 
post(this); 
} 
 
 
// Stop scrollingpublic void stopScroll() { 
isStop = true; 
} 
 
 
//Scroll from scratchpublic void startFromHead() { 
currentScrollX = 0; 
startScroll(); 
} 
} 

The code commented out above implements the text to the right

3. The following is the main program

import ; 
import ; 
import ; 
 
 
public class MainActivity extends Activity { 
 
 
private MarqueeText test; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
(savedInstanceState); 
setContentView(.activity_main); 
test=(MarqueeText) findViewById(); 
 
} 
public void start(View v){ 
(); 
} 
public void stop(View v){ 
(); 
} 
public void startFromHead(View v){ 
(); 
} 
} 


The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.