Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Toast View with Progress Animation Android, Left to Right

Need a solution to add a Shake View with a progress bar. This view is used as a Toast View in Android, I got a solution such that the View grows from the center and needs help in transforming into the expected result. The current state is zipped in the drive with the actual video & expected video.

Video and Current state source code

I tried this growFromCenter Extension function, I even tried using Object animator but got blocked while combining it with the progress bar.

private fun View.growFromCenter(
    duration: Long,
    @FloatRange(from = 0.0, to = 1.0)
    startScaleRatio: Float,
    endAnimCallback: () -> Unit = {},
) {
    val growFromCenter = ScaleAnimation(
        startScaleRatio,
        1f,
        startScaleRatio,
        1f,
        Animation.RELATIVE_TO_SELF,
        0.5f,
        Animation.RELATIVE_TO_SELF,
        0.5f
    )
    growFromCenter.duration = duration
    growFromCenter.fillAfter = true
    growFromCenter.interpolator = FastOutSlowInInterpolator()
    growFromCenter.setAnimationListener(object : Animation.AnimationListener {
        override fun onAnimationStart(p0: Animation?) {

        }

        override fun onAnimationEnd(p0: Animation?) {
            endAnimCallback.invoke()
        }

        override fun onAnimationRepeat(p0: Animation?) {

        }
    })

    startAnimation(growFromCenter)

}

like image 328
Sharan Avatar asked Oct 17 '25 15:10

Sharan


2 Answers

Use SnackProgressBar instead, I think it is better and easier to manage.

enter image description here

like image 59
Jabbar Avatar answered Oct 20 '25 07:10

Jabbar


Shake view with a progress bar

  • Step 1: In res/anim create file animation.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="true">
    <scale
     android:duration="350"
     android:fromXScale="0.0"
     android:fromYScale="0.5"
     android:pivotX="100%"
     android:pivotY="50%"
     android:toXScale="1.0"
     android:toYScale="1.0" />
    <translate
     android:duration="175"
     android:fromXDelta="0%"
     android:repeatCount="5"
     android:repeatMode="reverse"
     android:toXDelta="7%" />
    </set>
    
  • Step 2: In your require Activity

     class MainActivity : AppCompatActivity() {
     private val viewModel:MainActivityViewModel by viewModels()
     private  lateinit var  mBinding: ActivityMainBinding
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         mBinding=ActivityMainBinding.inflate(layoutInflater)
         setContentView(mBinding.root)
    
         viewModel.currentTime.observe(this) {
             val seconds = TimeUnit.MILLISECONDS.toSeconds(it*100)- TimeUnit.MINUTES.toSeconds(
                 TimeUnit.MILLISECONDS.toMinutes(it*100)
             )
             val minutes = TimeUnit.MILLISECONDS.toMinutes(it*100)
             Log.v("timmer", "$minutes : ${seconds}")
             mBinding.progressBar.progress = it.toInt()
    
         }
        mBinding.btn.setOnClickListener {
             mBinding.mtrlCardChecked.visibility= View.VISIBLE
            mBinding.progressBar.visibility=View.VISIBLE
            mBinding.mtrlCardChecked.startAnimation(AnimationUtils.loadAnimation(this, R.anim.animation))
            viewModel.timer(15000L)
            mBinding.progressBar.max=15*10
         }
    
    }}
    
  • Step 3: In ViewModel of your require activity

      package com.example.toasty
    
     import android.os.CountDownTimer
     import androidx.lifecycle.LiveData
     import androidx.lifecycle.MutableLiveData
     import androidx.lifecycle.ViewModel
    
    
    class MainActivityViewModel : ViewModel() {
    private var ONE_SEC = 100L
     lateinit var mCountDownTimer: CountDownTimer
    
     private val _currentTime: MutableLiveData<Long> = MutableLiveData<Long>(0)
     val currentTime: LiveData<Long> = _currentTime
     fun timer(countTimer: Long) {
         mCountDownTimer = object : CountDownTimer(countTimer, ONE_SEC) {
             override fun onTick(p0: Long) {
                 _currentTime.value = (p0 / ONE_SEC)
    
             }
             override fun onFinish() {
             }
         }
         mCountDownTimer.start()
     }
    

    }

  • Step 4: In your activity_main.xml file

     <?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:id="@+id/ctl"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     tools:context=".MainActivity">
    
     <com.google.android.material.button.MaterialButton
         android:id="@+id/btn"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="Hello Toasty!"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent" />
    
     <androidx.constraintlayout.widget.ConstraintLayout
         android:id="@+id/mtrl_card_checked"
         android:layout_width="match_parent"
         android:layout_height="100dp"
         android:layout_margin="10dp"
         android:visibility="gone"
         app:cardCornerRadius="3dp"
         app:cardElevation="12dp"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent">
    
         <View
             android:id="@+id/v_bar"
             android:layout_width="5dp"
             android:layout_height="90dp"
             android:background="@android:color/holo_green_light"
             app:layout_constraintBottom_toTopOf="@id/progressBar"
             app:layout_constraintStart_toStartOf="parent" />
    
         <androidx.appcompat.widget.AppCompatImageView
             android:id="@+id/iv_message_icon"
             android:layout_width="56dp"
             android:layout_height="56dp"
             android:background="@android:color/holo_green_light"
             android:src="@drawable/ic_launcher_foreground"
             app:layout_constraintBottom_toBottomOf="parent"
             app:layout_constraintStart_toEndOf="@id/v_bar"
             app:layout_constraintTop_toTopOf="parent" />
    
         <androidx.appcompat.widget.AppCompatImageView
             android:id="@+id/iv_message_icon_type"
             android:layout_width="20dp"
             android:layout_height="20dp"
             android:padding="4dp"
             app:layout_constraintBottom_toBottomOf="@id/iv_message_icon"
             app:layout_constraintEnd_toEndOf="@id/iv_message_icon" />
    
         <TextView
             android:id="@+id/tv_message"
             android:layout_width="0dp"
             android:layout_height="wrap_content"
             android:layout_marginEnd="5dp"
             android:text="You have too many players in the same position. To pick another, transfer one out. (2/2)"
             app:layout_constraintBottom_toBottomOf="@id/iv_message_icon"
             app:layout_constraintEnd_toStartOf="@id/iBtn_message_popup_close"
             app:layout_constraintStart_toEndOf="@id/iv_message_icon"
             app:layout_constraintTop_toTopOf="@id/iv_message_icon" />
    
         <androidx.appcompat.widget.AppCompatImageButton
             android:id="@+id/iBtn_message_popup_close"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_margin="6dp"
             android:background="?actionBarItemBackground"
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintTop_toTopOf="parent" />
    
         <com.google.android.material.progressindicator.LinearProgressIndicator
             android:id="@+id/progressBar"
             android:layout_width="0dp"
             android:layout_height="50dp"
             android:progress="10"
             android:secondaryProgressTintMode="screen"
             app:indicatorColor="@color/teal_200"
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintTop_toBottomOf="@id/v_bar"
             app:trackColor="@color/purple_200"
             app:trackThickness="10dp" />
    
     </androidx.constraintlayout.widget.ConstraintLayout>
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

enter image description here

You can directly download the sample project from Github repo

like image 39
Muhammad Ibrahim Avatar answered Oct 20 '25 07:10

Muhammad Ibrahim



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!