Circular Reveal is one of many cool animations introduced in Android 5.0. It’s easy to use, but the results are surprisingly cool and make your app even more awesome.
A, effects,
Without further ado, the GIF below uses the Circular Reveal animation to jump to the search page. GIF compression aspect ratio is distorted, but the effect is still there. Source code at the bottom, you can download the experience.
Circular Reveal introduction
Expose animations provide visual continuity for the user when you show or hide a set of UI elements.
ViewAnimationUtils. CreateCircularReveal () method allows you to add animation to cutting area to reveal or hide the view.
* @param view The View will be clipped to the animating circle.
* @param centerX The x coordinate of the center of the animating circle, relative to
* <code>view</code>.
* @param centerY The y coordinate of the center of the animating circle, relative to
* <code>view</code>.
* @param startRadius The starting radius of the animating circle.
* @param endRadius The ending radius of the animating circle.
*/
public static Animator createCircularReveal(View view,
int centerX, int centerY, float startRadius, float endRadius) {
return new RevealAnimator(view, centerX, centerY, startRadius, endRadius);
}Copy the code
ViewAnimationUtils. CreateCircularReveal () method to implement effect, is deleting a View into a circle, and then show the View from the center of the circle gradually revealed.
parameter | Parameters that |
---|---|
view | The View to animate |
centerX | The center x coordinate |
centerY | The center of the circle is y |
startRadius | The radius of the circle at the beginning |
endRadius | The radius of the circle at the end |
Three, implementation,
1. Animation parameters
@SuppressLint("NewApi")
private fun actionOtherVisible(isShow: Boolean, triggerView: View, animView: View) {
// Check whether the API is greater than 21
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
if (isShow) {
animView.visibility = View.VISIBLE
if(mListener ! =null) mListener!! .onShowAnimationEnd() }else {
animView.visibility = View.GONE
if(mListener ! =null) mListener!! .onHideAnimationEnd() }return
}
/** * Computes the center position of the triggerView(search button) */
val tvLocation = IntArray(2)
triggerView.getLocationInWindow(tvLocation)
val tvX = tvLocation[0] + triggerView.width / 2
val tvY = tvLocation[1] + triggerView.height / 2
/** * Calculates the center position of the animView(that is, the root layout) */
val avLocation = IntArray(2)
animView.getLocationInWindow(avLocation)
val avX = avLocation[0] + animView.width / 2
val avY = avLocation[1] + animView.height / 2
// Calculate the width and height
val rippleW = if (tvX < avX) animView.width - tvX else tvX - avLocation[0]
val rippleH = if (tvY < avY) animView.height - tvY else tvY - avLocation[1]
// Pythagorean theorem for hypotenuse
val maxRadius = Math.sqrt((rippleW * rippleW + rippleH * rippleH).toDouble()).toFloat()
val startRadius: Float
val endRadius: Float
// Set the start and end radii according to show or hide
if (isShow) {
startRadius = 0f
endRadius = maxRadius
} else {
startRadius = maxRadius
endRadius = 0f
}
val anim = ViewAnimationUtils.createCircularReveal(animView, tvX, tvY, startRadius, endRadius)
animView.visibility = View.VISIBLE
anim.duration = DURATION
anim.interpolator = DecelerateInterpolator()
// Listen for the animation to end and make a callback
anim.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation)
if (isShow) {
animView.visibility = View.VISIBLE
if(mListener ! =null) mListener!! .onShowAnimationEnd() }else {
animView.visibility = View.GONE
if(mListener ! =null) mListener!! .onHideAnimationEnd() } } }) anim.start() }Copy the code
The comments in the code above clearly parse the process of getting and executing the animation parameters.
2. Animation call
fun show(triggerView: View, showView: View) {
actionOtherVisible(true, triggerView, showView)
}
fun hide(triggerView: View, hideView: View) {
actionOtherVisible(false, triggerView, hideView)
}Copy the code
The actionOtherVisible() method determines whether to perform a show or hide animation based on passing true/false.
3. Animation call timing
In the SearchFragment, listen for the first frame to draw and animate. The mRootView is the root layout View.
override fun onPreDraw(a): Boolean {
iv_search_search.viewTreeObserver.removeOnPreDrawListener(this);
mCircularRevealAnim.show(iv_search_search, mRootView);
return true;
}Copy the code
Animation end call time: ① Click search, jump to the search results interface. ② The physical rollback key is rolled back. ③ Click the rollback button
The hide() method can be called in any of these three places to hide the animation.
4. Listen for callbacks
When you configure the animation parameters above, a listening callback is made to the end of the animation. The onHideAnimationEnd() and onShowAnimationEnd() methods of the AnimListener interface are called to implement the callback. So implement this interface in the SearchFragment to listen for callbacks.
override fun onHideAnimationEnd(a) {
et_search_keyword.setText("");
dismiss();
}
override fun onShowAnimationEnd(a) {
if(isVisible) { KeyBoardUtils.openKeyboard(activity, et_search_keyword); }}Copy the code
When the hidden animation ends, call the Dismiss () method to close the DialogFragment. At the end of the monitor display, open the input box.
It’s that simple and you can achieve such a cool effect through the above methods.
Github Address: Search page Circular Reveal animation