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)
}
Use SnackProgressBar
instead, I think it is better and easier to manage.
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>
You can directly download the sample project from Github repo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With