애니메이션으로 뷰 표시 또는 숨기기

Compose 방식 사용해 보기
Jetpack Compose는 Android에 권장되는 UI 도구 키트입니다. Compose에서 애니메이션을 사용하는 방법을 알아보세요.
<ph type="x-smartling-placeholder"></ph> 크로스페이드 → 를 통해 개인정보처리방침을 정의할 수 있습니다.

앱이 사용되는 동안 새로운 정보가 화면에 표시되고 기존 정보가 표시됩니다. 삭제됩니다. 화면에 즉시 표시되는 항목을 변경할 수도 있습니다. 사용자는 갑자기 나타나는 새 콘텐츠를 놓칠 수 있습니다. 애니메이션이 느림 변경사항을 아래로 내리고 움직임으로 사용자의 시선을 끌어 업데이트가 더 분명해집니다.

뷰를 표시하거나 숨기는 데 사용할 수 있는 일반적인 애니메이션에는 세 가지가 있습니다. 애니메이션, 크로스페이드 애니메이션, 카드플립 애니메이션입니다.

크로스페이드 애니메이션 만들기

디졸브라고도 하는 크로스페이드 애니메이션은 점진적으로 페이드 아웃됩니다. View 1개 또는 동시에 ViewGroup 또 하나는 페이드인됩니다. 이 애니메이션은 전환할 수 있습니다 여기에 표시된 크로스페이드 애니메이션은 ViewPropertyAnimator님, (Android 3.1(API 수준 12) 이상에서 사용 가능)

다음은 진행률 표시기에서 텍스트 콘텐츠로 바뀌는 크로스페이드의 예입니다.

<ph type="x-smartling-placeholder">
그림 1. 크로스페이드 애니메이션

뷰 만들기

크로스페이드할 뷰를 두 개 만듭니다. 다음 예에서는 진행률 표시기와 스크롤 가능한 텍스트 뷰를 제공합니다.

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView style="?android:textAppearanceMedium"
            android:lineSpacingMultiplier="1.2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/lorem_ipsum"
            android:padding="16dp" />

    </ScrollView>

    <ProgressBar android:id="@+id/loading_spinner"
        style="?android:progressBarStyleLarge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center" />

</FrameLayout>

크로스페이드 애니메이션 설정

크로스페이드 애니메이션을 설정하려면 다음 단계를 따르세요.

  1. 크로스페이드할 뷰의 멤버 변수를 만들어야 합니다. 요구사항 나중에 애니메이션 중에 뷰를 수정할 때 이러한 참조를 조정할 수 있습니다.
  2. 페이드인되는 뷰의 표시 여부 설정 GONE 이렇게 하면 레이아웃 계산에서 이를 생략하여 업처리 중
  3. config_shortAnimTime 캐시 시스템 속성을 지정해야 합니다. 이 속성은 표준 'short'를 정의합니다. 시간을 설정할 수 있습니다. 이 시간은 섬세한 애니메이션이나 자주 발생하는 애니메이션입니다. config_longAnimTime 드림 및 config_mediumAnimTime 도 사용할 수 있습니다.

다음은 이전 코드 스니펫의 레이아웃을 활동 콘텐츠 뷰:

Kotlin

class CrossfadeActivity : Activity() {

    private lateinit var contentView: View
    private lateinit var loadingView: View
    private var shortAnimationDuration: Int = 0
    ...
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_crossfade)

        contentView = findViewById(R.id.content)
        loadingView = findViewById(R.id.loading_spinner)

        // Initially hide the content view.
        contentView.visibility = View.GONE

        // Retrieve and cache the system's default "short" animation time.
        shortAnimationDuration = resources.getInteger(android.R.integer.config_shortAnimTime)
    }
    ...
}

자바

public class CrossfadeActivity extends Activity {

    private View contentView;
    private View loadingView;
    private int shortAnimationDuration;
    ...
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_crossfade);

        contentView = findViewById(R.id.content);
        loadingView = findViewById(R.id.loading_spinner);

        // Initially hide the content view.
        contentView.setVisibility(View.GONE);

        // Retrieve and cache the system's default "short" animation time.
        shortAnimationDuration = getResources().getInteger(
                android.R.integer.config_shortAnimTime);
    }
    ...
}

뷰 크로스페이드

뷰가 적절히 설정되었으면 다음을 실행하여 뷰를 크로스페이드합니다.

  1. 페이드인되는 뷰의 경우 알파 값을 0으로 설정하고 가시성을 설정합니다. 초기 값에서 VISIBLEGONE의 설정입니다. 이렇게 하면 뷰가 표시되지만 투명해집니다.
  2. 페이드인되는 뷰의 알파 값을 0에서 1로 애니메이션 처리합니다. 대상 페이드아웃되는 뷰를 생성할 때 알파 값을 1에서 0으로 애니메이션 처리합니다.
  3. 사용 onAnimationEnd() 드림 , Animator.AnimatorListener, 페이드 아웃되는 뷰의 가시성을 GONE로 설정합니다. 그러나 알파 값이 0인 경우 뷰의 공개 상태를 GONE로 설정하면 뷰가 차단됩니다. 레이아웃 계산에서 이를 생략하여 많은 시간을 절약할 수 있습니다

다음은 이 작업을 어떻게 수행하는지를 보여주는 예제입니다.

Kotlin

class CrossfadeActivity : Activity() {

    private lateinit var contentView: View
    private lateinit var loadingView: View
    private var shortAnimationDuration: Int = 0
    ...
    private fun crossfade() {
        contentView.apply {
            // Set the content view to 0% opacity but visible, so that it is
            // visible but fully transparent during the animation.
            alpha = 0f
            visibility = View.VISIBLE

            // Animate the content view to 100% opacity and clear any animation
            // listener set on the view.
            animate()
                    .alpha(1f)
                    .setDuration(shortAnimationDuration.toLong())
                    .setListener(null)
        }
        // Animate the loading view to 0% opacity. After the animation ends,
        // set its visibility to GONE as an optimization step so it doesn't
        // participate in layout passes.
        loadingView.animate()
                .alpha(0f)
                .setDuration(shortAnimationDuration.toLong())
                .setListener(object : AnimatorListenerAdapter() {
                    override fun onAnimationEnd(animation: Animator) {
                        loadingView.visibility = View.GONE
                    }
                })
    }
}

자바

public class CrossfadeActivity extends Activity {

    private View contentView;
    private View loadingView;
    private int shortAnimationDuration;
    ...
    private void crossfade() {

        // Set the content view to 0% opacity but visible, so that it is
        // visible but fully transparent during the animation.
        contentView.setAlpha(0f);
        contentView.setVisibility(View.VISIBLE);

        // Animate the content view to 100% opacity and clear any animation
        // listener set on the view.
        contentView.animate()
                .alpha(1f)
                .setDuration(shortAnimationDuration)
                .setListener(null);

        // Animate the loading view to 0% opacity. After the animation ends,
        // set its visibility to GONE as an optimization step so it doesn't
        // participate in layout passes.
        loadingView.animate()
                .alpha(0f)
                .setDuration(shortAnimationDuration)
                .setListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        loadingView.setVisibility(View.GONE);
                    }
                });
    }
}

카드플립 애니메이션 만들기

카드를 플립하면 에뮬레이션하는 애니메이션을 표시하여 콘텐츠 뷰 간 전환 카드가 뒤집어집니다. 여기에 표시된 카드플립 애니메이션에서는 FragmentTransaction

다음은 카드플립 애니메이션입니다.

<ph type="x-smartling-placeholder">
그림 2. 카드플립 애니메이션

애니메이터 객체 만들기

카드플립 애니메이션을 만들려면 4개의 애니메이터가 필요합니다. 두 애니메이터는 카드 앞면이 애니메이션 및 왼쪽으로 애니메이션될 때와 안팎으로 들어갑니다. 나머지 두 애니메이터는 카드 뒷면의 가 애니메이션/오른쪽에서 애니메이션으로 바뀌었고 오른쪽으로

card_flip_left_in.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Before rotating, immediately set the alpha to 0. -->
    <objectAnimator
        android:valueFrom="1.0"
        android:valueTo="0.0"
        android:propertyName="alpha"
        android:duration="0" />

    <!-- Rotate. -->
    <objectAnimator
        android:valueFrom="-180"
        android:valueTo="0"
        android:propertyName="rotationY"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:duration="@integer/card_flip_time_full" />

    <!-- Halfway through the rotation, set the alpha to 1. See startOffset. -->
    <objectAnimator
        android:valueFrom="0.0"
        android:valueTo="1.0"
        android:propertyName="alpha"
        android:startOffset="@integer/card_flip_time_half"
        android:duration="1" />
</set>

card_flip_left_out.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Rotate. -->
    <objectAnimator
        android:valueFrom="0"
        android:valueTo="180"
        android:propertyName="rotationY"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:duration="@integer/card_flip_time_full" />

    <!-- Halfway through the rotation, set the alpha to 0. See startOffset. -->
    <objectAnimator
        android:valueFrom="1.0"
        android:valueTo="0.0"
        android:propertyName="alpha"
        android:startOffset="@integer/card_flip_time_half"
        android:duration="1" />
</set>

card_flip_right_in.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Before rotating, immediately set the alpha to 0. -->
    <objectAnimator
        android:valueFrom="1.0"
        android:valueTo="0.0"
        android:propertyName="alpha"
        android:duration="0" />

    <!-- Rotate. -->
    <objectAnimator
        android:valueFrom="180"
        android:valueTo="0"
        android:propertyName="rotationY"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:duration="@integer/card_flip_time_full" />

    <!-- Halfway through the rotation, set the alpha to 1. See startOffset. -->
    <objectAnimator
        android:valueFrom="0.0"
        android:valueTo="1.0"
        android:propertyName="alpha"
        android:startOffset="@integer/card_flip_time_half"
        android:duration="1" />
</set>

card_flip_right_out.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Rotate. -->
    <objectAnimator
        android:valueFrom="0"
        android:valueTo="-180"
        android:propertyName="rotationY"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:duration="@integer/card_flip_time_full" />

    <!-- Halfway through the rotation, set the alpha to 0. See startOffset. -->
    <objectAnimator
        android:valueFrom="1.0"
        android:valueTo="0.0"
        android:propertyName="alpha"
        android:startOffset="@integer/card_flip_time_half"
        android:duration="1" />
</set>

뷰 만들기

카드의 각 면에 원하는 콘텐츠를 포함할 수 있는 별도의 레이아웃은 (예: 두 개의 텍스트 뷰, 두 개의 이미지 또는 뒤집을 뷰 조합) 있습니다. 나중에 애니메이션을 적용할 프래그먼트에서 두 개의 레이아웃을 사용합니다. 이 다음 레이아웃은 텍스트를 표시하는 카드의 한 면을 만듭니다.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#a6c"
    android:padding="16dp"
    android:gravity="bottom">

    <TextView android:id="@android:id/text1"
        style="?android:textAppearanceLarge"
        android:textStyle="bold"
        android:textColor="#fff"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/card_back_title" />

    <TextView style="?android:textAppearanceSmall"
        android:textAllCaps="true"
        android:textColor="#80ffffff"
        android:textStyle="bold"
        android:lineSpacingMultiplier="1.2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/card_back_description" />

</LinearLayout>

다음 레이아웃에서는 카드의 다른 면을 만들고, 여기에 ImageView:

<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:src="@drawable/image1"
    android:scaleType="centerCrop"
    android:contentDescription="@string/description_image_1" />

프래그먼트 만들기

카드의 앞면과 뒷면을 위한 프래그먼트 클래스를 만듭니다. 프래그먼트에서 클래스에서 만든 레이아웃을 반환하려면 onCreateView() 드림 메서드를 사용하여 축소하도록 요청합니다. 그런 다음 상위 활동에서 이 프래그먼트의 인스턴스를 만들 수 있습니다. 선택합니다.

다음 예는 상위 활동 내에 중첩된 프래그먼트 클래스를 보여줍니다. 다음과 같습니다.

Kotlin

class CardFlipActivity : FragmentActivity() {
    ...
    /**

                    *   A fragment representing the front of the card.
     */
    class CardFrontFragment : Fragment() {

    override fun onCreateView(
                inflater: LayoutInflater,
                container: ViewGroup?,
                savedInstanceState: Bundle?
    ): View = inflater.inflate(R.layout.fragment_card_front, container, false)
    }

    /**
    *   A fragment representing the back of the card.
    */
    class CardBackFragment : Fragment() {

    override fun onCreateView(
                inflater: LayoutInflater,
                container: ViewGroup?,
                savedInstanceState: Bundle?
    ): View = inflater.inflate(R.layout.fragment_card_back, container, false)
    }
}

자바

public class CardFlipActivity extends FragmentActivity {
    ...
    /**
    *   A fragment representing the front of the card.
    */
    public class CardFrontFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            return inflater.inflate(R.layout.fragment_card_front, container, false);
    }
    }

    /**
    *   A fragment representing the back of the card.
    */
    public class CardBackFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            return inflater.inflate(R.layout.fragment_card_back, container, false);
    }
    }
}

카드플립 애니메이션

상위 활동 내에 프래그먼트를 표시합니다. 이렇게 하려면 정의합니다. 다음 예에서는 추가할 수 있는 FrameLayout 런타임 시 프래그먼트에 전달합니다.

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

활동 코드에서 콘텐츠 뷰를 직접 만든 레이아웃으로 설정합니다. 활동이 생성될 때 기본 프래그먼트를 표시하는 것이 좋습니다. 이 다음 예시 활동은 카드 앞면을 표시하는 방법을 보여줍니다. 기본값:

Kotlin

class CardFlipActivity : FragmentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_activity_card_flip)
        if (savedInstanceState == null) {
            supportFragmentManager.beginTransaction()
                    .add(R.id.container, CardFrontFragment())
                    .commit()
        }
    }
    ...
}

자바

public class CardFlipActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_activity_card_flip);

        if (savedInstanceState == null) {
            getSupportFragmentManager()
                    .beginTransaction()
                    .add(R.id.container, new CardFrontFragment())
                    .commit();
        }
    }
    ...
}

카드 앞면을 표시하면 카드 뒷면을 볼 수 있으며 플립 애니메이션을 사용하세요. 데이터 레이크의 반대쪽을 표시하는 메서드를 만듭니다. 다음 작업을 수행하는 카드입니다.

  • 프래그먼트 전환을 위해 만든 맞춤 애니메이션을 설정합니다.
  • 표시된 프래그먼트를 새 프래그먼트로 바꾸고 이 이벤트에 애니메이션을 적용합니다. 만들 수 있습니다.
  • 이전에 표시된 프래그먼트를 프래그먼트 백 스택에 추가하므로 사용자가 뒤로 버튼을 탭하면 카드가 다시 뒤집힙니다.

Kotlin

class CardFlipActivity : FragmentActivity() {
    ...
    private fun flipCard() {
        if (showingBack) {
            supportFragmentManager.popBackStack()
            return
        }

        // Flip to the back.

        showingBack = true

        // Create and commit a new fragment transaction that adds the fragment
        // for the back of the card, uses custom animations, and is part of the
        // fragment manager's back stack.

        supportFragmentManager.beginTransaction()

                // Replace the default fragment animations with animator
                // resources representing rotations when switching to the back
                // of the card, as well as animator resources representing
                // rotations when flipping back to the front, such as when the
                // system Back button is tapped.
                .setCustomAnimations(
                        R.animator.card_flip_right_in,
                        R.animator.card_flip_right_out,
                        R.animator.card_flip_left_in,
                        R.animator.card_flip_left_out
                )

                // Replace any fragments in the container view with a fragment
                // representing the next page, indicated by the just-incremented
                // currentPage variable.
                .replace(R.id.container, CardBackFragment())

                // Add this transaction to the back stack, letting users press
                // the Back button to get to the front of the card.
                .addToBackStack(null)

                // Commit the transaction.
                .commit()
    }
}

자바

public class CardFlipActivity extends FragmentActivity {
    ...
    private void flipCard() {
        if (showingBack) {
            getSupportFragmentManager().popBackStack();
            return;
        }

        // Flip to the back.

        showingBack = true;

        // Create and commit a new fragment transaction that adds the fragment
        // for the back of the card, uses custom animations, and is part of the
        // fragment manager's back stack.

        getSupportFragmentManager()
                .beginTransaction()

                // Replace the default fragment animations with animator
                // resources representing rotations when switching to the back
                // of the card, as well as animator resources representing
                // rotations when flipping back to the front, such as when the
                // system Back button is pressed.
                .setCustomAnimations(
                        R.animator.card_flip_right_in,
                        R.animator.card_flip_right_out,
                        R.animator.card_flip_left_in,
                        R.animator.card_flip_left_out)

                // Replace any fragments in the container view with a fragment
                // representing the next page, indicated by the just-incremented
                // currentPage variable.
                .replace(R.id.container, new CardBackFragment())

                // Add this transaction to the back stack, letting users press
                // Back to get to the front of the card.
                .addToBackStack(null)

                // Commit the transaction.
                .commit();
    }
}

회전 표시 애니메이션 만들기

그룹을 표시하거나 숨길 때 사용자에게 시각적 연속성을 제공하는 애니메이션 표시 UI 요소가 있습니다. 이 ViewAnimationUtils.createCircularReveal() 드림 메서드를 사용하면 뷰를 표시하거나 숨기도록 클리핑 서클에 애니메이션을 적용할 수 있습니다. 이 애니메이션은 ViewAnimationUtils 클래스 (Android 5.0(API 수준 21) 이상에서 사용 가능)

다음은 이전에 보이지 않았던 뷰를 표시하는 방법을 보여주는 예제입니다.

Kotlin

// A previously invisible view.
val myView: View = findViewById(R.id.my_view)

// Check whether the runtime version is at least Android 5.0.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    // Get the center for the clipping circle.
    val cx = myView.width / 2
    val cy = myView.height / 2

    // Get the final radius for the clipping circle.
    val finalRadius = Math.hypot(cx.toDouble(), cy.toDouble()).toFloat()

    // Create the animator for this view. The start radius is 0.
    val anim = ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0f, finalRadius)
    // Make the view visible and start the animation.
    myView.visibility = View.VISIBLE
    anim.start()
} else {
    // Set the view to invisible without a circular reveal animation below
    // Android 5.0.
    myView.visibility = View.INVISIBLE
}

자바

// A previously invisible view.
View myView = findViewById(R.id.my_view);

// Check whether the runtime version is at least Android 5.0.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    // Get the center for the clipping circle.
    int cx = myView.getWidth() / 2;
    int cy = myView.getHeight() / 2;

    // Get the final radius for the clipping circle.
    float finalRadius = (float) Math.hypot(cx, cy);

    // Create the animator for this view. The start radius is 0.
    Animator anim = ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0f, finalRadius);

    // Make the view visible and start the animation.
    myView.setVisibility(View.VISIBLE);
    anim.start();
} else {
    // Set the view to invisible without a circular reveal animation below
    // Android 5.0.
    myView.setVisibility(View.INVISIBLE);
}

ViewAnimationUtils.createCircularReveal() 애니메이션에는 5개의 매개변수가 사용됩니다. 첫 번째 매개변수는 화면에서 숨기거나 표시할 뷰입니다. 이 다음 두 매개변수는 클리핑 중심에 대한 X 및 Y 좌표입니다. 있습니다. 일반적으로 이 위치가 뷰의 중심이지만, 사용자가 탭하여 선택한 지점에서 애니메이션이 시작되도록 합니다. 이 네 번째 매개변수는 클리핑 서클의 시작 반경입니다.

이전 예에서는 초기 반지름이 0으로 설정되어 뷰가 원에 의해 숨겨집니다. 마지막 매개변수는 표시됩니다. 보기를 표시할 때 최종 반경을 애니메이션이 완료되기 전에 뷰가 완전히 표시될 수 있도록 합니다.

이전에 표시된 뷰를 숨기려면 다음 단계를 따르세요.

Kotlin

// A previously visible view.
val myView: View = findViewById(R.id.my_view)

// Check whether the runtime version is at least Android 5.0.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    // Get the center for the clipping circle.
    val cx = myView.width / 2
    val cy = myView.height / 2

    // Get the initial radius for the clipping circle.
    val initialRadius = Math.hypot(cx.toDouble(), cy.toDouble()).toFloat()

    // Create the animation. The final radius is 0.
    val anim = ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0f)

    // Make the view invisible when the animation is done.
    anim.addListener(object : AnimatorListenerAdapter() {

        override fun onAnimationEnd(animation: Animator) {
            super.onAnimationEnd(animation)
            myView.visibility = View.INVISIBLE
        }
    })

    // Start the animation.
    anim.start()
} else {
    // Set the view to visible without a circular reveal animation below
    // Android 5.0.
    myView.visibility = View.VISIBLE
}

자바

// A previously visible view.
final View myView = findViewById(R.id.my_view);

// Check whether the runtime version is at least Android 5.0.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    // Get the center for the clipping circle.
    int cx = myView.getWidth() / 2;
    int cy = myView.getHeight() / 2;

    // Get the initial radius for the clipping circle.
    float initialRadius = (float) Math.hypot(cx, cy);

    // Create the animation. The final radius is 0.
    Animator anim = ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0f);

    // Make the view invisible when the animation is done.
    anim.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
            myView.setVisibility(View.INVISIBLE);
        }
    });

    // Start the animation.
    anim.start();
} else {
    // Set the view to visible without a circular reveal animation below Android
    // 5.0.
    myView.setVisibility(View.VISIBLE);
}

이 경우 클리핑 서클의 초기 반지름은 애니메이션이 시작되기 전에 뷰가 표시되도록 합니다. 마지막 애니메이션이 끝나면 뷰가 숨겨지도록 반경이 0으로 설정됩니다. 뷰의 가시성을 다음과 같이 설정할 수 있도록 애니메이션에 리스너를 추가합니다. 애니메이션이 실행되었을 때 INVISIBLE 나타냅니다.

추가 리소스