ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Android] Circular Reveal Amimation
    프로그래밍/Android 2019. 1. 9. 17:16

    이번 포스팅은 애니메이션 효과에 대해 말해볼까 합니다.

    요즘 새로 나오는 어플들을 보면 단순히 페이지를 넘길 때나 스크롤 할 때 등 사용자의 반응에 따라 애니메이션 효과가 적용되어있는 것을 볼 수 있습니다. 딱 보기에도 뭔가 있어 보이는게 좋아보이네요. 저희도 뒤쳐질 수 없겠죠?


    그럼 포스팅을 시작하겠습니다.




    Circular Reveal Animation?

    이름부터 생소하신 분들이 많을 거라고 예상합니다. 저 또한 그랬는데요, 흔히 알고 있던 크기 또는 투명도를 조절하거나 회전을 주는 등의 애니메이션이 아닌 새로운 애니메이션 효과에 신기하기만 했었던 것만 같습니다.


    그럼 Circular Reveal Animation은 어떤 애니메이션 일까요?


    Circular Reveal Animation 예시



    위의 예시에서 Fab 버튼을 눌렀을 때, 원형으로 퍼져나가는 효과가 바로 Circular Reveal Animation 효과입니다. 물론 애니메이션 속도나 원의 반경 등은 조절이 가능합니다. 이어서 사용법에 대해 알아보도록 하겠습니다.



    Circular Revael Animation 사용하기

    먼저 레이아웃을 구성하도록 하겠습니다.


    activity_main.xml



    <?xml version="1.0" encoding="utf-8"?>

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

        xmlns:app="http://schemas.android.com/apk/res-auto"

        xmlns:tools="http://schemas.android.com/tools"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        tools:context="rebuild.com.circularrevealanimation.MainActivity">


        <RelativeLayout

            android:id="@+id/layout_main"

            android:layout_width="match_parent"

            android:layout_height="match_parent">


            <TextView

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:layout_centerInParent="true"

                android:text="숲속의 작은 이야기"

                android:textSize="30dp" />

        </RelativeLayout>


        <RelativeLayout

            android:id="@+id/layout_content"

            android:layout_width="match_parent"

            android:layout_height="match_parent"

            android:background="#009688">


            <TextView

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:layout_centerInParent="true"

                android:text="숲속의 작은 이야기"

                android:textColor="#FFFFFF"

                android:textSize="30dp" />

        </RelativeLayout>


        <android.support.design.widget.FloatingActionButton

            android:id="@+id/fab_toggle"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_alignParentBottom="true"

            android:layout_alignParentRight="true"

            android:layout_marginBottom="20dp"

            android:layout_marginRight="20dp"

            android:src="@drawable/ic_add"

            app:backgroundTint="#009688"

            app:borderWidth="0dp"

            app:fabSize="normal" />


    </RelativeLayout>


    기본적으로 보여지는 main화면과 fab 버튼을 눌렀을 때 보여질 content 레이아웃으로 구성하였습니다.


    Fab 버튼에 대한 내용은 이전 포스트를 참고해주시기 바랍니다.


    FloatingActionButton 사용하기

    http://re-build.tistory.com/31



    이어서, Activity를 구성해 보겠습니다.


    MainActivity.java



    package rebuild.com.circularrevealanimation;


    import android.animation.Animator;

    import android.content.Context;

    import android.content.res.ColorStateList;

    import android.graphics.Color;

    import android.os.Bundle;

    import android.support.design.widget.FloatingActionButton;

    import android.support.v7.app.AppCompatActivity;

    import android.view.View;

    import android.view.ViewAnimationUtils;

    import android.widget.RelativeLayout;


    public class MainActivity extends AppCompatActivity implements View.OnClickListener {

        private Context mContext;


        private RelativeLayout layout_content;

        private FloatingActionButton fab_toggle;


        private boolean isOpen = false;


        @Override

        protected void onCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);

            setContentView(R.layout.activity_main);

            mContext = this;


            init();

        }


        private void init() {

            layout_content = (RelativeLayout) findViewById(R.id.layout_content);

            layout_content.setVisibility(View.INVISIBLE);


            fab_toggle = (FloatingActionButton) findViewById(R.id.fab_toggle);

            fab_toggle.setOnClickListener(this);

        }


        private void showReveal() {

            int centerX = (int) fab_toggle.getX() + fab_toggle.getWidth() / 2;

            int centerY = (int) fab_toggle.getY() + fab_toggle.getHeight() / 2;


            int radius = (int) Math.hypot(layout_content.getWidth(), layout_content.getHeight());


            if (isOpen) {

                fab_toggle.setBackgroundTintList(ColorStateList.valueOf(Color.parseColor("#009688")));

                fab_toggle.setImageResource(R.drawable.ic_add);


                Animator revealAnimator = ViewAnimationUtils

    .createCircularReveal(layout_content, centerX, centerY, radius, 0);

                revealAnimator.addListener(mRevealAnimatorListener);

                revealAnimator.setDuration(300);

                revealAnimator.start();

            } else {

                fab_toggle.setBackgroundTintList(ColorStateList.valueOf(Color.parseColor("#FFFFFF")));

                fab_toggle.setImageResource(R.drawable.ic_close);


                Animator revealAnimator = ViewAnimationUtils

    .createCircularReveal(layout_content, centerX, centerY, 0, radius);

                revealAnimator.setDuration(300);

                layout_content.setVisibility(View.VISIBLE);

                revealAnimator.start();

            }


            isOpen = !isOpen;

        }


        @Override

        public void onClick(View v) {

            switch (v.getId()) {

                case R.id.fab_toggle:

                    showReveal();

                    break;

            }

        }


        private Animator.AnimatorListener mRevealAnimatorListener = new Animator.AnimatorListener() {

            @Override

            public void onAnimationStart(Animator animation) {

            }


            @Override

            public void onAnimationEnd(Animator animation) {

                layout_content.setVisibility(View.INVISIBLE);

            }


            @Override

            public void onAnimationCancel(Animator animation) {

            }


            @Override

            public void onAnimationRepeat(Animator animation) {

            }


            @Override

            public void onAnimationStart(Animator animation, boolean isReverse) {

            }


            @Override

            public void onAnimationEnd(Animator animation, boolean isReverse) {

            }

        };

    }


    주요 부분은 굵게 표시된 부분인데요, 자세히 한번 보겠습니다.


    createCircularReveal(View tagetView, int centerX, int centerY, float startRadius, float endRadius)


    • View tagetView

    - 애니메이션을 적용 할 타겟이 되는 뷰를 지정합니다.


    • centerX

    - 애니메이션의 중심이 되는 x좌표 값을 지정합니다.


    • centerY

    - 애니메이션의 중심이 되는  y좌표 값을 지정합니다.


    • startRadius

    - 애니메이션 시작 시점의 원의 반경을 지정합니다.


    • endRadius

    - 애니메이션 종료 시점의 원의 반경을 지정합니다.


    보기보다 사용이 굉장히 간단하죠?

    주의하실 점은 애니메이션이 일단 시작되면 끝날 때까지 중간에 정지 할 수 없다는 점과 재 사용이 불가능 하다는 점 입니다.


    간단하게 예제를 통해서 Circular Reveal Animation에 대해서 알아봤는데요, 도움이 좀 되셨을까요?

    다음 포스팅도 조만간 올리도록 노력하겠습니다.

    이상으로 포스팅을 마치겠습니다.








Designed by Tistory.