Shri
Shri

Reputation: 1243

How to animate the textview (very very long text )scroll automatically horizontally

I am not interested in Marquee because, in Marquee you can not control the speed of marquee. I have tried to animate the textview but Parent view clips the text at the end even though all parent layout and view groups encompassing textviews are set with two flags clipchildren= false, clipToPadding=false.

Am I missing something or is there a better work around ?

The xml looks like

<TextView
        android:id="@+id/textview1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_marginBottom="66dp"
        android:maxLines="1"
        android:singleLine="true"
        android:textColor="#585858"
        android:textSize="32sp" >
    </TextView>

and code snippet look like

TextView textView2 = (TextView)findViewById( R.id.textview1 );    
textView2.startAnimation((Animation)AnimationUtils.loadAnimation(this, R.anim.translate));

Upvotes: 9

Views: 22890

Answers (11)

Wong Je Yi
Wong Je Yi

Reputation: 1

Its really frustrating,... But the answer is simple, Use Edittext instead of TextView, and wrap it in horizontalscrollview At the same time, setfocusable: false

   <HorizontalScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:scrollbars="none">

        <EditText
            android:id="@+id/post_message"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="15dp"
            android:focusable="false"
            android:outlineAmbientShadowColor="@color/colorPrimaryDark"
            android:shadowColor="#000000"
            android:shadowDx="1.5"
            android:shadowDy="1.3"
            android:shadowRadius="1.6"
            android:singleLine="true"
            android:textAlignment="center"
            android:textColor="@color/colorPrimary"
            android:textSize="20dp" />
    </HorizontalScrollView>

Thanks to Hein, add the animation code

final EditText textView =  view.findViewById(R.id.post_message);
        textView.startAnimation((Animation) AnimationUtils.loadAnimation(context,R.anim.horizontal_animation));
        String message="LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLong Text.";
        textView.setText(message);

Upvotes: 0

Aman Ranjan Verma
Aman Ranjan Verma

Reputation: 189

I am sure this will definitely solve the problem of the large audience out there.

Q: Auto-scroll a single line long text message(either using hard_coding or from string.xml) horizontally & infinitely at a reasonable speed but using marquee(try it once at least). No clipping

Step 1: In activity_main.xml file:

<TextView
    android:text="either hard coding or from string.xml"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/textView2"  
    android:background="@color/colorPrimary"
    android:textSize="18sp"
    android:marqueeRepeatLimit="marquee_forever"
    android:textColor="@android:color/background_light" />

Step 2: In main_activity java file public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    TextView textView = (TextView) findViewById(R.id.textView2);
    textView.setEllipsize(TextUtils.TruncateAt.MARQUEE);
    textView.setSelected(true);
    textView.setSingleLine(true);
    textView.setText("Oxfam says 8 men as rich as half the world. | Govt may set threshold for probe into deposits. | At least 32 dead after Turkish plane hits village.");}}

//one can remove the last line line if he has already feed the long input

Upvotes: 9

user3056315
user3056315

Reputation: 11

Add this Animation file:

<translate
    android:duration="7000"
    android:fromYDelta="0%p"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:repeatCount="10"
    android:repeatMode="restart"
    android:toYDelta="-100%p" />

/*Put your text view inside scroll*/
        <ScrollView
            android:layout_width="@dimen/dp_size_220"
            android:layout_height="@dimen/dp_size_16"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toRightOf="@+id/iv_myra_notification"
            app:layout_constraintRight_toLeftOf="@+id/iv_one_way"
            app:layout_constraintTop_toTopOf="parent">
            <TextView
                android:id="@+id/marquee_text"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="left"
                android:text="@{itemData.notification.message}"
                android:textColor="@android:color/black"
                android:textSize="12sp"
                tools:text="bfnfkjnvlen jknjkgnojeng"/>
        </ScrollView>

Upvotes: 1

Suresh Kodoor
Suresh Kodoor

Reputation: 21

Can try out this. This is a solution using TranslateAnimation for creating an auto scrolling text (horizontal scroll, from Right to Left) (Tested on Android 8)

Class: AnimationAutoTextScroller.java

/**
 * A Class for automatically scrolling text horizontally from Right to Left 
 * using TranslateAnimation so that the scrolling speed can be controlled -Suresh Kodoor
 */

public class AnimationAutoTextScroller {

    Animation animator;
    TextView  scrollingTextView;
    int       duration = 50000;  // default value

    public AnimationAutoTextScroller(TextView tv, float screenwidth) {

        this.scrollingTextView = tv;
        this.animator = new TranslateAnimation(
                Animation.ABSOLUTE, screenwidth,
                Animation.RELATIVE_TO_SELF, -1f,
                Animation.RELATIVE_TO_SELF, 0f,
                Animation.RELATIVE_TO_SELF, 0f
        );
        this.animator.setInterpolator(new LinearInterpolator());
        this.animator.setDuration(this.duration);
        this.animator.setFillAfter(true);
        this.animator.setRepeatMode(Animation.RESTART);
        this.animator.setRepeatCount(Animation.INFINITE);

        // setAnimationListener();
    }

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

    public void setScrollingText(String text) {
        this.scrollingTextView.setText(text);
    }

    public void start() {
        this.scrollingTextView.setSelected(true);
        this.scrollingTextView.startAnimation(this.animator);
    }

    public void setAnimationListener() {

        animator.setAnimationListener(new Animation.AnimationListener() {
            public void onAnimationStart(Animation animation) {
            }
            public void onAnimationEnd(Animation animation) {
                // This callback function can be used to perform any task at the end of the Animation
            }
            public void onAnimationRepeat(Animation animation) {
            }
        });
    }
}

Layout XML: (keep the TextView under a HorizontalScrollView)

 <HorizontalScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="none"
        app:layout_constraintBottom_toTopOf="@+id/hguide3"
        app:layout_constraintEnd_toStartOf="@+id/vguide2"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toEndOf="@+id/vguide1"
        app:layout_constraintTop_toBottomOf="@+id/hguide2">

    <TextView
        android:id="@+id/translateanimatortextviewscroller"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="0dp"
        android:layout_marginEnd="0dp"
        android:layout_marginLeft="0dp"
        android:layout_marginStart="0dp"
        android:layout_marginTop="0dp"
        android:text=""
        android:singleLine="true"
        android:focusable="true"
        android:scrollHorizontally="true"
        android:background="#000000ff"
        android:textColor="#ff0000"
        android:textSize="55dp"
        android:textStyle="bold"
        android:typeface="sans" />

      </HorizontalScrollView>

Activity:

TextView scrollertextview = findViewById(R.id.translateanimatortextviewscroller);
textscroller = new AnimationAutoTextScroller(scrollertextview, screenwidth);
textscroller.setScrollingText(scrollertext);
textscroller.setDuration(60000);
textscroller.start();

Upvotes: 2

Hem&#227; Vidal
Hem&#227; Vidal

Reputation: 1872

Use this simple way with ellipsize and marquee options using @rajath answer

<TextView
    android:text="Single-line text view that scrolls automatically if the text is too long to fit in the widget" 
    android:singleLine="true"
    android:ellipsize="marquee"
    android:marqueeRepeatLimit ="marquee_forever"
    android:focusable="true"
    android:focusableInTouchMode="true" 
    android:scrollHorizontally="true"
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content"/>

Upvotes: 0

Shengfeng Li
Shengfeng Li

Reputation: 644

Here was my SOLUTION

To make the long text inside textview not be cut by parent view or by screen, I have done two things.

First, let textview inside a scroolview like below code

<ScrollView
    android:layout_width="wrap_content"
    android:layout_height="50dp"
    android:layout_centerHorizontal="true">
    <TextView
        android:id="@+id/marquee_text"
        android:layout_width="wrap_content"
        android:layout_height="50dp"
        android:maxLines="1"
        android:textColor="@android:color/black"
        android:textSize="30sp"/>
</ScrollView>

Then, I measure my text size then refine the textview param by doing this.

    marqueeText.setText("my long text");
    Paint textPaint = marqueeText.getPaint();
    String text = marqueeText.getText().toString();//get text
    int width = Math.round(textPaint.measureText(text));//measure the text size
    ViewGroup.LayoutParams params =  marqueeText.getLayoutParams();
    params.width = width;
    marqueeText.setLayoutParams(params); //refine

    DisplayMetrics displaymetrics = new DisplayMetrics();
    getActivity().getWindowManager().getDefaultDisplay().getRealMetrics(displaymetrics);
    int screenWidth = displaymetrics.widthPixels;

    //this is optional. do not scroll if text is shorter than screen width
    //remove this won't effect the scroll
    if (width <= screenWidth) {
        //All text can fit in screen.
        return;
    }
    //set the animation
    TranslateAnimation slide = new TranslateAnimation(0, -width, 0, 0);
    slide.setDuration(20000);
    slide.setRepeatCount(Animation.INFINITE);
    slide.setRepeatMode(Animation.RESTART);
    slide.setInterpolator(new LinearInterpolator());
    marqueeText.startAnimation(slide);

I hope this solution which took me half a day to research can help others who might meet the same problem like me.

Upvotes: 4

Harish Reddy
Harish Reddy

Reputation: 992

Just add this to your textview

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ellipsize="marquee"
    android:textSize="30dp"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:marqueeRepeatLimit="marquee_forever"
    android:scrollHorizontally="true"
    android:singleLine="true"
    android:text="Your_Text" />

Upvotes: 5

Siddharth jain
Siddharth jain

Reputation: 447

This is what worked for me. Place your textview inside a scroll view and then perform TranslateAnimation on the scrollview's child, my case its the LinearLayout. I am actually adding multiple views dynamically inside this linear layout.

<ScrollView android:id="@+id/textScrollView"
    android:layout_width="wrap_content"
    android:layout_height="match_parent">
    <LinearLayout
        android:id="@+id/textLayout"
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
    </LinearLayout>
</ScrollView>

TranslateAnimation slide = new TranslateAnimation(0, 0, height, -textLayout.getHeight());
    slide.setDuration(movementSpeed);
    slide.setRepeatCount(-1);
    slide.setRepeatMode(Animation.RESTART);
    slide.setInterpolator(new LinearInterpolator());

textLayout.startAnimation(slide);

height --> The point start scrolling up (in my case device height (device bottom))
movementSpeed --> scrolling speed

Upvotes: 0

charan28
charan28

Reputation: 11

try this code it will help you out Shri n HERO

<?xml version="1.0" encoding="utf-8"?>
<translate>
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="5000"
    android:fromXDelta="1500"
    android:interpolator="@android:anim/linear_interpolator"
    android:repeatCount="infinite"
    android:repeatMode="restart"
    android:toXDelta="-1250" />

</translate>

Upvotes: 0

charan28
charan28

Reputation: 11

<translate>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="5000"
android:fromXDelta="1500"
android:interpolator="@android:anim/linear_interpolator"
android:repeatCount="infinite"
android:repeatMode="restart"
android:toXDelta="-1250" />

Upvotes: -1

Hein
Hein

Reputation: 2683

I think you can use translate animation. Something like this

<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="5000"
    android:fromXDelta="100"
    android:interpolator="@android:anim/linear_interpolator"
    android:repeatCount="infinite"
    android:repeatMode="restart"
    android:toXDelta="-100" />

And add to your textview like this

textview.startAnimation((Animation)AnimationUtils.loadAnimation(Context,R.anim.scroll_animation));

Hope it can help you.

Upvotes: 7

Related Questions