-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add group view to sync multiple SkelletonView class
- Loading branch information
1 parent
d0b10c0
commit 74844fd
Showing
12 changed files
with
334 additions
and
139 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
76 changes: 76 additions & 0 deletions
76
android/src/main/java/com/reactnativeskelleton/SkelletonGroupView.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package com.reactnativeskelleton | ||
|
||
import android.animation.AnimatorSet | ||
import android.animation.ObjectAnimator | ||
import android.annotation.SuppressLint | ||
import android.os.Handler | ||
import android.util.Log | ||
import android.view.View | ||
import android.view.ViewGroup | ||
import android.view.animation.* | ||
import com.facebook.react.uimanager.ThemedReactContext | ||
import com.facebook.react.views.view.ReactViewGroup | ||
import kotlin.collections.ArrayList | ||
|
||
|
||
@SuppressLint("ViewConstructor") | ||
class SkelletonGroupView(reactContext: ThemedReactContext): ReactViewGroup(reactContext) { | ||
private val animatorSet = AnimatorSet() | ||
private val objectAnimatorList = ArrayList<ObjectAnimator>() | ||
|
||
private fun buildAnimatorSet() { | ||
Handler().post { | ||
objectAnimatorList.clear() | ||
|
||
getSkelletonViewAnimator(this) | ||
|
||
animatorSet.playTogether(objectAnimatorList.toList()) | ||
|
||
animatorSet.start() | ||
} | ||
} | ||
|
||
private fun getSkelletonViewAnimator(view: View) { | ||
if (view !is ViewGroup) { return } | ||
|
||
for (i in 0 until view.childCount) { | ||
val child = view.getChildAt(i) | ||
|
||
getSkelletonViewAnimator(child) | ||
} | ||
|
||
if(view is SkelletonView) { | ||
objectAnimatorList.add(view.objectAnimator) | ||
} | ||
} | ||
|
||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { | ||
super.onMeasure(widthMeasureSpec, heightMeasureSpec) | ||
|
||
buildAnimatorSet() | ||
} | ||
|
||
fun setDuration(duration: Int) { | ||
animatorSet.duration = duration.toLong() | ||
} | ||
|
||
fun setStartDelay(delay: Int) { | ||
animatorSet.startDelay = delay.toLong() | ||
} | ||
|
||
fun setInterpolator(interpolator: String) { | ||
animatorSet.interpolator = when(interpolator) { | ||
"AccelerateDecelerateInterpolator" -> AccelerateDecelerateInterpolator() | ||
"AccelerateInterpolator" -> AccelerateInterpolator() | ||
"AnticipateInterpolator" -> AnticipateInterpolator() | ||
"AnticipateOvershootInterpolator" -> AnticipateOvershootInterpolator() | ||
"BounceInterpolator" -> BounceInterpolator() | ||
"CycleInterpolator" -> CycleInterpolator(1f) | ||
"DecelerateInterpolator" -> DecelerateInterpolator() | ||
"LinearInterpolator" -> LinearInterpolator() | ||
"OvershootInterpolator" -> OvershootInterpolator() | ||
|
||
else -> AccelerateDecelerateInterpolator() | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
106 changes: 106 additions & 0 deletions
106
android/src/main/java/com/reactnativeskelleton/SkelletonView.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
package com.reactnativeskelleton | ||
|
||
import android.animation.Animator | ||
import android.animation.ObjectAnimator | ||
import android.animation.ValueAnimator | ||
import android.annotation.SuppressLint | ||
import android.os.Handler | ||
import android.view.animation.* | ||
import com.facebook.react.uimanager.ThemedReactContext | ||
import com.facebook.react.views.view.ReactViewGroup | ||
|
||
@SuppressLint("ViewConstructor") | ||
class SkelletonView(reactContext: ThemedReactContext) : ReactViewGroup(reactContext) { | ||
private val startInitialPosition = -9999f | ||
private val endInitialPosition = 0f | ||
private var repeatDelay: Long = 0 | ||
private var measured = false | ||
|
||
var objectAnimator: ObjectAnimator = ObjectAnimator.ofFloat(this, "translationX", startInitialPosition, endInitialPosition) | ||
|
||
init { | ||
// set initial position to maintain the user experience | ||
translationX = startInitialPosition | ||
|
||
objectAnimator.addListener(SkelletonAnimatorListener()) | ||
} | ||
|
||
override fun onLayout(p0: Boolean, p1: Int, p2: Int, p3: Int, p4: Int) {} | ||
|
||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { | ||
super.onMeasure(widthMeasureSpec, heightMeasureSpec) | ||
|
||
objectAnimator.setFloatValues(-(measuredWidth + 1).toFloat(), (measuredWidth + 1).toFloat()) | ||
|
||
measured = true | ||
} | ||
|
||
fun setDuration(duration: Int) { | ||
objectAnimator.duration = duration.toLong() | ||
} | ||
|
||
fun setStartDelay(delay: Int) { | ||
objectAnimator.startDelay = delay.toLong() | ||
} | ||
|
||
fun setRepeatDelay(delay: Int) { | ||
repeatDelay = delay.toLong() | ||
} | ||
|
||
fun setRepeatCount(count: Int) { | ||
objectAnimator.repeatCount = count | ||
} | ||
|
||
fun setRepeatMode(mode: Int) { | ||
val repeatMode = when(mode) { | ||
ValueAnimator.RESTART -> ValueAnimator.RESTART | ||
else -> ValueAnimator.REVERSE | ||
} | ||
|
||
objectAnimator.repeatMode = repeatMode | ||
} | ||
|
||
fun setInterpolator(interpolator: String) { | ||
objectAnimator.interpolator = when(interpolator) { | ||
"AccelerateDecelerateInterpolator" -> AccelerateDecelerateInterpolator() | ||
"AccelerateInterpolator" -> AccelerateInterpolator() | ||
"AnticipateInterpolator" -> AnticipateInterpolator() | ||
"AnticipateOvershootInterpolator" -> AnticipateOvershootInterpolator() | ||
"BounceInterpolator" -> BounceInterpolator() | ||
"CycleInterpolator" -> CycleInterpolator(1f) | ||
"DecelerateInterpolator" -> DecelerateInterpolator() | ||
"LinearInterpolator" -> LinearInterpolator() | ||
"OvershootInterpolator" -> OvershootInterpolator() | ||
|
||
else -> AccelerateDecelerateInterpolator() | ||
} | ||
} | ||
|
||
fun setAutoStart(autoStart: Boolean) { | ||
if(measured) return | ||
|
||
if(autoStart) { | ||
objectAnimator.cancel() | ||
objectAnimator.start() | ||
} | ||
} | ||
|
||
private inner class SkelletonAnimatorListener: Animator.AnimatorListener { | ||
override fun onAnimationRepeat(animator: Animator?) { | ||
animator?.let { | ||
if(repeatDelay > 0) { | ||
it.pause() | ||
|
||
Handler().postDelayed(it::resume, repeatDelay) | ||
} | ||
} | ||
} | ||
|
||
override fun onAnimationEnd(animator: Animator?) {} | ||
|
||
override fun onAnimationCancel(animator: Animator?) {} | ||
|
||
override fun onAnimationStart(animator: Animator?) {} | ||
|
||
} | ||
} |
Oops, something went wrong.