2

I am creating video app like TikTok and need to implement text marquee in TextView. I also recorded video for doing same like this

So I created TextView code:

<LinearLayout
    android:id="@+id/llSoundDesc"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginStart="20dp"
    android:layout_marginBottom="5dp"
    android:orientation="horizontal"
    app:layout_constraintBottom_toTopOf="@+id/tabLayout"
    app:layout_constraintEnd_toStartOf="@+id/layoutSound"
    app:layout_constraintStart_toStartOf="parent"
    tools:ignore="UseCompoundDrawables">

    <ImageView
        android:layout_width="15dp"
        android:layout_height="15dp"
        android:layout_gravity="center"
        android:contentDescription="@string/app_name"
        android:src="@mipmap/ic_music" />

    <TextView
        android:id="@+id/tvSoundDesc"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginBottom="2dp"
        android:ellipsize="marquee"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:marqueeRepeatLimit="marquee_forever"
        android:scrollHorizontally="true"
        android:singleLine="true"
        android:text="@string/orignal_soun_by"
        android:textColor="@color/white" />
</LinearLayout>

And from HomeActivity.kt:

class HomeActivity : AppCompatActivity() {
    private lateinit var mBinding: ActivityHomeBinding
    private var isPlay = false

    @SuppressLint("ClickableViewAccessibility")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mBinding = ActivityHomeBinding.inflate(layoutInflater)
        setContentView(mBinding.root)

        mBinding.tvSoundDesc.isSelected = true
    }
}

So, this code will show text in marquee continuously but not smoothly after one marquee freeze for few millis and then start again and there is also another problem is how can I play/pause like TikTok app?

I also tried:

btn.setOnClickListener {
    if (isPlay) {
        isPlay = false
        mBinding.tvSoundDesc.isSelected = false
    } else {
        isPlay = true
        mBinding.tvSoundDesc.isSelected = true
    }
}

but its start from first position not from current position like TikTok App! And I also tried <marquee>Your text</marquee> of HTML and set to TextView but it also not working. So, is there any other way to set marquee like this?

Jayesh Rathod
  • 600
  • 1
  • 5
  • 18

1 Answers1

0

You can use ObjectAnimator for the marquee effect and can control the animation as you like. Here is an example implementation of the ObjectAnimator for your use case:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tvText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_resume"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Resume"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/btn_pause"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent" />

    <Button
        android:id="@+id/btn_pause"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Pause"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/btn_resume" />

</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.kt

import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.animation.LinearInterpolator
import org.imaginativeworld.experimentapp.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)


        binding.root.post {
            val halfViewWidth = (binding.root.width + binding.tvText.width) / 2f

            val animator = ObjectAnimator.ofFloat(
                binding.tvText,
                "translationX",
                -halfViewWidth,
                halfViewWidth
            ).apply {
                duration = 5000
                repeatCount = ValueAnimator.INFINITE
                interpolator = LinearInterpolator()
                start()
            }

            binding.btnResume.setOnClickListener {
                animator.resume()
            }

            binding.btnPause.setOnClickListener {
                animator.pause()
            }
        }

    }
}

The code is self-explanatory.

More help: https://developer.android.com/guide/topics/graphics/prop-animation#object-animator

Mahmudul Hasan Shohag
  • 2,203
  • 1
  • 22
  • 30