@@ -29,13 +29,17 @@ import android.view.View
2929import androidx.annotation.DrawableRes
3030import androidx.appcompat.widget.TooltipCompat
3131import androidx.dynamicanimation.animation.DynamicAnimation
32+ import androidx.lifecycle.LifecycleOwner
33+ import androidx.lifecycle.lifecycleScope
3234import androidx.vectordrawable.graphics.drawable.Animatable2Compat
3335import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat
3436import com.github.shadowsocks.R
3537import com.github.shadowsocks.bg.BaseService
3638import com.google.android.material.floatingactionbutton.FloatingActionButton
3739import com.google.android.material.progressindicator.BaseProgressIndicator
3840import com.google.android.material.progressindicator.DeterminateDrawable
41+ import kotlinx.coroutines.Job
42+ import kotlinx.coroutines.delay
3943import java.util.*
4044
4145class ServiceButton @JvmOverloads constructor(context : Context , attrs : AttributeSet ? = null , defStyleAttr : Int = 0 ) :
@@ -59,7 +63,7 @@ class ServiceButton @JvmOverloads constructor(context: Context, attrs: Attribute
5963 }
6064
6165 private inner class AnimatedState (@DrawableRes resId : Int ,
62- private val onStart : BaseProgressIndicator <* >.() -> Unit = { hide () }) {
66+ private val onStart : BaseProgressIndicator <* >.() -> Unit = { hideProgress () }) {
6367 val icon: AnimatedVectorDrawableCompat = AnimatedVectorDrawableCompat .create(context, resId)!! .apply {
6468 registerAnimationCallback(this @ServiceButton.callback)
6569 }
@@ -74,16 +78,25 @@ class ServiceButton @JvmOverloads constructor(context: Context, attrs: Attribute
7478 private val iconStopped by lazy { AnimatedState (R .drawable.ic_service_stopped) }
7579 private val iconConnecting by lazy {
7680 AnimatedState (R .drawable.ic_service_connecting) {
77- hide()
78- isIndeterminate = true
79- show()
81+ hideProgress()
82+ delayedAnimation = (context as LifecycleOwner ).lifecycleScope.launchWhenStarted {
83+ delay(context.resources.getInteger(android.R .integer.config_mediumAnimTime) + 1000L )
84+ isIndeterminate = true
85+ show()
86+ }
87+ }
88+ }
89+ private val iconConnected by lazy {
90+ AnimatedState (R .drawable.ic_service_connected) {
91+ delayedAnimation?.cancel()
92+ setProgressCompat(1 , true )
8093 }
8194 }
82- private val iconConnected by lazy { AnimatedState (R .drawable.ic_service_connected) { setProgressCompat(1 , true ) } }
8395 private val iconStopping by lazy { AnimatedState (R .drawable.ic_service_stopping) }
8496 private val animationQueue = ArrayDeque <AnimatedState >()
8597
8698 private var checked = false
99+ private var delayedAnimation: Job ? = null
87100 private lateinit var progress: BaseProgressIndicator <* >
88101 fun initProgress (progress : BaseProgressIndicator <* >) {
89102 this .progress = progress
@@ -94,6 +107,11 @@ class ServiceButton @JvmOverloads constructor(context: Context, attrs: Attribute
94107 if (! canceled) progress.hide()
95108 }
96109
110+ private fun hideProgress () {
111+ delayedAnimation?.cancel()
112+ progress.hide()
113+ }
114+
97115 override fun onCreateDrawableState (extraSpace : Int ): IntArray {
98116 val drawableState = super .onCreateDrawableState(extraSpace + 1 )
99117 if (checked) View .mergeDrawableStates(drawableState, intArrayOf(android.R .attr.state_checked))
0 commit comments