Skip to content

Instantly share code, notes, and snippets.

@makovkastar
Last active May 23, 2018 13:04
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 makovkastar/904843dca7ed4e6efcefc0a9ecbf468f to your computer and use it in GitHub Desktop.
Save makovkastar/904843dca7ed4e6efcefc0a9ecbf468f to your computer and use it in GitHub Desktop.
import android.content.Context
import android.os.SystemClock
import android.support.v4.widget.SwipeRefreshLayout
import android.util.AttributeSet
/**
* ContentLoadingSwipeRefreshLayout implements a SwipeRefreshLayout that waits a minimum time to
* dismiss the refreshing indicator before showing. Once visible, the refreshing indicator will be
* visible for a minimum amount of time to avoid "flashes" in the UI when an event could take
* a largely variable time to complete (from none, to a user perceivable amount).
*/
class ContentLoadingSwipeRefreshLayout(
context: Context,
attrs: AttributeSet
) : SwipeRefreshLayout(context, attrs) {
private companion object {
const val MIN_SHOW_TIME_MS = 500L
const val MIN_DELAY_MS = 500L
const val TIME_NOT_SET = -1L
}
private var startTime = TIME_NOT_SET
private var postedHide = false
private var postedShow = false
private var dismissed = false
private val delayedShow = Runnable {
postedShow = false
if (!dismissed) {
startTime = SystemClock.elapsedRealtime()
super.setRefreshing(true)
}
}
private val delayedHide = Runnable {
postedHide = false
startTime = TIME_NOT_SET
super.setRefreshing(false)
}
override fun setRefreshing(refreshing: Boolean) {
if (refreshing) {
showRefreshing()
} else {
hideRefreshing()
}
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
removeCallbacks()
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
removeCallbacks()
}
private fun showRefreshing() {
startTime = TIME_NOT_SET
dismissed = false
removeCallbacks(delayedHide)
if (!postedShow) {
postDelayed(delayedShow, MIN_DELAY_MS)
postedShow = true
}
}
private fun hideRefreshing() {
dismissed = true
removeCallbacks(delayedShow)
val timeDiff = System.currentTimeMillis() - startTime
if (timeDiff >= MIN_SHOW_TIME_MS || startTime == TIME_NOT_SET) {
// The refreshing indicator has been shown long enough
// or was not shown yet. If it wasn't shown yet,
// it will just never be shown.
super.setRefreshing(false)
} else {
// The refreshing indicator is shown, but not long enough,
// so put a delayed message in to hide it when its been
// shown long enough.
if (!postedHide) {
postDelayed(delayedHide, MIN_SHOW_TIME_MS - timeDiff)
postedHide = true
}
}
}
private fun removeCallbacks() {
removeCallbacks(delayedShow)
removeCallbacks(delayedHide)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment