Skip to content

Instantly share code, notes, and snippets.

@webserveis
Created May 12, 2020 09:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save webserveis/a835de0ff4170d447f95e8b33fa5518d to your computer and use it in GitHub Desktop.
Save webserveis/a835de0ff4170d447f95e8b33fa5518d to your computer and use it in GitHub Desktop.
RevelCicleView reveal effect for show view

Usage:

        fab.setOnClickListener {
            myContainer.showWithRevealEffect()
        }

        closeButton.setOnClickListener {
            myContainer.hideWithRevealEffect()
        }

        myContainer.setOnRevealListener(object : RevealCircleView.RevealListener {
            override fun onHide() {
                Toast.makeText(this@MainActivity, "on Hi8de", Toast.LENGTH_SHORT).show()
            }

        })
package com.webserveis.testbannerview
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.content.Context
import android.os.Handler
import android.os.Parcel
import android.os.Parcelable
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.view.ViewAnimationUtils
import android.view.animation.AccelerateDecelerateInterpolator
import android.widget.LinearLayout
import androidx.core.view.isVisible
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlin.math.hypot
/*
https://github.com/xiprox/NamazVakitleri/blob/master/mobile/src/main/kotlin/tr/xip/prayertimes/ui/widget/RelativeTimeTextView.kt
*/
open class RevealCircleView : LinearLayout {
interface RevealListener {
fun onHide()
}
private var isRevelating = false
private var callback: RevealListener? = null
private var isAutoHide = false
private var mHandler: Handler = Handler()
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(
context,
attrs,
defStyle
)
init {
Log.d(TAG, "Init component: ")
runAutoHide()
}
override fun onSaveInstanceState(): Parcelable? {
val savedState = SavedState(super.onSaveInstanceState())
savedState.isVisible = this.isVisible
return savedState
}
override fun onRestoreInstanceState(state: Parcelable?) {
if (state is SavedState) {
super.onRestoreInstanceState(state.superState)
this.visibility = if (state.isVisible) View.VISIBLE else View.INVISIBLE
} else {
super.onRestoreInstanceState(state)
}
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
mHandler.removeCallbacksAndMessages(null)
}
fun setOnRevealListener(callback: RevealListener) {
this.callback = callback
}
fun showWithRevealEffect() {
val view = this
if (view.isVisible) return
val cx = view.width / 2
val cy = view.height / 2
// get the final radius for the clipping circle
val finalRadius = hypot(
view.width.toDouble(),
view.height.toDouble()
).toFloat()
// create the animator for this view (the start radius is zero)
if (!isAttachedToWindow) return
val anim =
ViewAnimationUtils.createCircularReveal(view, cx, cy, 0F, finalRadius).apply {
interpolator = AccelerateDecelerateInterpolator()
}
//anim.duration = 1200
// make the view visible and start the animation
view.visibility = View.VISIBLE
anim.start()
runAutoHide()
}
private fun runAutoHide() {
mHandler = Handler()
mHandler.postDelayed({
hideWithRevealEffect()
}, 5000)
}
fun hideWithRevealEffect() {
val view = this
if (!view.isVisible || isRevelating) return
isRevelating = true
val cx = view.width / 2
val cy = view.height / 2
// get the initial radius for the clipping circle
val initialRadius = hypot(
view.width.toDouble(),
view.height.toDouble()
).toFloat()
// create the animation (the final radius is zero)
if (!isAttachedToWindow) return
val anim =
ViewAnimationUtils.createCircularReveal(view, cx, cy, initialRadius, 0F).apply {
interpolator = AccelerateDecelerateInterpolator()
//duration = 5000
}
// make the view invisible when the animation is done
anim.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation)
callback?.onHide()
view.visibility = View.INVISIBLE
isRevelating = false
}
})
// start the animation
anim.start()
}
companion object {
private val TAG = RevealCircleView::class.java.simpleName
}
internal class SavedState : BaseSavedState {
var isVisible = false
constructor(source: Parcel) : super(source) {
isVisible = source.readByte().toInt() != 0
}
constructor(superState: Parcelable?) : super(superState)
override fun writeToParcel(out: Parcel, flags: Int) {
super.writeToParcel(out, flags)
out.writeByte((if (isVisible) 1 else 0).toByte())
}
companion object {
@JvmField
val CREATOR: Parcelable.Creator<SavedState> = object : Parcelable.Creator<SavedState> {
override fun createFromParcel(source: Parcel): SavedState? {
return SavedState(source)
}
override fun newArray(size: Int): Array<SavedState?> {
return arrayOfNulls(size)
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment