با استفاده از انیمیشن یک نما را آشکار یا پنهان کنید

روش Compose را امتحان کنید
Jetpack Compose جعبه ابزار UI توصیه شده برای اندروید است. نحوه استفاده از انیمیشن ها در Compose را بیاموزید.

هنگامی که برنامه شما در حال استفاده است، اطلاعات جدید روی صفحه ظاهر می شود و اطلاعات قدیمی حذف می شوند. تغییر فورا آنچه روی صفحه نمایش داده می‌شود می‌تواند آزاردهنده باشد و کاربران می‌توانند محتوای جدیدی را که به‌طور ناگهانی ظاهر می‌شوند از دست بدهند. انیمیشن ها سرعت تغییرات را کاهش می دهند و چشم کاربر را با حرکت جلب می کنند تا به روز رسانی ها بیشتر نمایان شوند.

سه انیمیشن متداول وجود دارد که می‌توانید از آنها برای نمایش یا پنهان کردن یک نما استفاده کنید: انیمیشن‌های آشکار، انیمیشن‌های متقاطع، و انیمیشن‌های کارتی.

یک انیمیشن crossfade ایجاد کنید

یک انیمیشن متقاطع - که به عنوان dissolve نیز شناخته می شود - به تدریج یک View یا ViewGroup را محو می کند در حالی که به طور همزمان در دیگری محو می شود. این انیمیشن برای موقعیت‌هایی مفید است که می‌خواهید محتوا یا نماها را در برنامه خود تغییر دهید. انیمیشن crossfade نشان داده شده در اینجا از ViewPropertyAnimator استفاده می‌کند که برای Android 3.1 (سطح API 12) و بالاتر در دسترس است.

در اینجا یک مثال از یک crossfade از نشانگر پیشرفت به محتوای متن آورده شده است:

شکل 1. انیمیشن Crossfade.

نماها را ایجاد کنید

دو نما را ایجاد کنید که می خواهید متقاطع شوند. مثال زیر یک نشانگر پیشرفت و یک نمای متنی قابل پیمایش ایجاد می کند:

<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>

انیمیشن crossfade را تنظیم کنید

برای تنظیم انیمیشن crossfade، موارد زیر را انجام دهید:

  1. متغیرهای عضو را برای نماهایی که می خواهید crossfade کنید ایجاد کنید. بعداً هنگام اصلاح نماها در طول انیمیشن به این مراجع نیاز دارید.
  2. نمایان بودن نمای محو شده را روی GONE تنظیم کنید. این کار از استفاده از فضای چیدمان توسط نما جلوگیری می کند و آن را از محاسبات چیدمان حذف می کند که پردازش را سرعت می بخشد.
  3. ویژگی سیستم config_shortAnimTime را در یک متغیر عضو کش کنید. این ویژگی یک مدت زمان استاندارد "کوتاه" را برای انیمیشن تعریف می کند. این مدت زمان برای انیمیشن های ظریف یا انیمیشن هایی که مکررا رخ می دهند ایده آل است. config_longAnimTime و config_mediumAnimTime نیز در دسترس هستند.

در اینجا یک مثال با استفاده از طرح بندی از قطعه کد قبلی به عنوان نمای محتوای فعالیت آورده شده است:

کاتلین

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 و نمایان بودن را روی VISIBLE از تنظیمات اولیه GONE تنظیم کنید. این باعث می شود نما قابل مشاهده اما شفاف باشد.
  2. برای نمایی که در حال محو شدن است، مقدار آلفای آن را از 0 به 1 متحرک کنید. برای نمای که در حال محو شدن است، مقدار آلفا را از 1 به 0 متحرک کنید.
  3. با استفاده از onAnimationEnd() در Animator.AnimatorListener ، نمایان بودن نمای محو شده را روی GONE تنظیم کنید. حتی با وجود اینکه مقدار آلفا 0 است، تنظیم نمایان شدن نما بر روی GONE از استفاده از فضای طرح بندی و حذف آن از محاسبات طرح حذف می شود، که پردازش را سرعت می بخشد.

روش زیر نمونه ای از نحوه انجام این کار را نشان می دهد:

کاتلین

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 استفاده می کند.

در اینجا یک تلنگر کارت به نظر می رسد:

شکل 2. انیمیشن برگرداندن کارت.

اشیاء انیماتور را ایجاد کنید

برای ایجاد انیمیشن کارت، به چهار انیماتور نیاز دارید. دو انیماتور برای زمانی هستند که جلوی کارت به بیرون و به سمت چپ متحرک می شود و زمانی که در داخل و از چپ متحرک می شود. دو انیماتور دیگر برای زمانی هستند که پشت کارت در داخل و از راست متحرک می شود و زمانی که به بیرون و به راست متحرک می شود.

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() ایجاد کرده‌اید، برگردانید. سپس می توانید نمونه هایی از این قطعه را در فعالیت والد که می خواهید کارت را نشان دهید ایجاد کنید.

مثال زیر کلاس های قطعه تو در تو را در داخل اکتیویتی والد نشان می دهد که از آنها استفاده می کند:

کاتلین

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" />

در کد فعالیت، نمای محتوا را طوری تنظیم کنید که طرحی باشد که ایجاد می کنید. این تمرین خوبی است که هنگام ایجاد اکتیویتی، یک قطعه پیش فرض را نشان دهید. فعالیت مثال زیر نحوه نمایش جلوی کارت را به طور پیش فرض نشان می دهد:

کاتلین

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();
        }
    }
    ...
}

با نشان دادن قسمت جلوی کارت، می توانید پشت کارت را با انیمیشن چرخشی در زمان مناسب نشان دهید. روشی برای نشان دادن طرف دیگر کارت ایجاد کنید که کارهای زیر را انجام می دهد:

  • انیمیشن های سفارشی که برای انتقال قطعه ایجاد کرده اید را تنظیم می کند.
  • قطعه نمایش داده شده را با یک قطعه جدید جایگزین می کند و این رویداد را با انیمیشن های سفارشی که ایجاد کرده اید متحرک می کند.
  • قطعه نمایش داده شده قبلی را به پشته قطعه اضافه می کند، بنابراین وقتی کاربر روی دکمه برگشت ضربه می زند، کارت به عقب برمی گردد.

کاتلین

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();
    }
}

یک انیمیشن آشکار دایره ای ایجاد کنید

هنگامی که شما گروهی از عناصر رابط کاربری را نشان می‌دهید یا پنهان می‌کنید، انیمیشن‌های آشکار، تداوم بصری را برای کاربران فراهم می‌کنند. متد ViewAnimationUtils.createCircularReveal() به شما امکان می دهد یک دایره برش را متحرک کنید تا یک نما را آشکار یا پنهان کنید. این انیمیشن در کلاس ViewAnimationUtils ارائه شده است که برای اندروید 5.0 (سطح API 21) و بالاتر در دسترس است.

در اینجا یک مثال نشان می دهد که چگونه یک نمای قبلی نامرئی را نشان می دهد:

کاتلین

// 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() پنج پارامتر دارد. اولین پارامتر نمایه ای است که می خواهید مخفی کنید یا روی صفحه نمایش دهید. دو پارامتر بعدی مختصات X و Y برای مرکز دایره برش هستند. به طور معمول، این مرکز دید است، اما می‌توانید از نقطه‌ای که کاربر روی آن ضربه می‌زند تا انیمیشن از جایی که انتخاب می‌کند شروع شود، استفاده کنید. پارامتر چهارم شعاع شروع دایره برش است.

در مثال قبلی، شعاع اولیه روی صفر تنظیم شده است تا نمای نمایش داده شده توسط دایره پنهان شود. آخرین پارامتر شعاع نهایی دایره است. هنگام نمایش یک نما، شعاع نهایی را بزرگتر از نما قرار دهید تا قبل از اتمام انیمیشن، نمای کاملاً آشکار شود.

برای مخفی کردن نمای قبلی قابل مشاهده، موارد زیر را انجام دهید:

کاتلین

// 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);
}

در این حالت شعاع اولیه دایره برش به اندازه نما تنظیم می شود تا نمای قبل از شروع انیمیشن قابل مشاهده باشد. شعاع نهایی روی صفر تنظیم شده است تا پس از اتمام انیمیشن، نمای پنهان شود. یک شنونده به انیمیشن اضافه کنید تا پس از اتمام انیمیشن، نمایان شدن نما روی INVISIBLE تنظیم شود.

منابع اضافی