본문 바로가기
Android/Concepts

Page Sliding 구현하기

by JuHy_ 2020. 5. 8.

Page Sliding이란?

Navigation Drawer와 같이 화면이 왼쪽이나 오른쪽에서 스르륵 나오도록 구현하려면 어떻게 해야할까?

이런 기능을 Page Sliding이라고 하며, 레이아웃 위에 다른 레이아웃을 중첩시켜 표현하게 된다.

일반적인 상황에는 중첩된 레이아웃을 숨겨놓았다가 애니메이션과 함께 보여주면 된다.

 

※ 애니메이션이 사용되므로 애니메이션을 모른다면 미리 아래 글을 통해 참고하자.

 

Animation 사용법

Tween Animation이란? Thread Animation의 경우 애니메이션을 구현하려면 프레임당 1장씩 많은 양의 이미지가 필요하다. 이 때문에 단순히 이미지가 움직일 경우 이미지의 위치를 바꿔 뿌려주는 것이 자원을 아낄..

ju-hy.tistory.com

 

구현 방법

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:background="#FF5555FF">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Base Area"
            android:textSize="30sp"
            android:textColor="#FFFFFF" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/page"
        android:layout_width="200dp"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:layout_gravity="right"
        android:background="#FFFFFF66"
        android:visibility="gone" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Sliding Area"
            android:textSize="30sp"
            android:textColor="#000000" />

    </LinearLayout>

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="open"
        android:layout_gravity="center_vertical|right"/>

</FrameLayout>

먼저 최상위 레이아웃을 FrameLayout으로 두고 화면을 모두 채우는 Base Area를 만들어준다.

그리고 화면 오른쪽에 200dp 넓이의 레이아웃을 중첩시켜 만든 뒤 visibility를 gone으로 만들어 숨겨주자.

 

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <translate
        android:fromXDelta="0%p"
        android:toXDelta="100%p"
        android:duration="1000" />

</set>

▲translate_right.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <translate
        android:fromXDelta="100%p"
        android:toXDelta="0%p"
        android:duration="1000" />

</set>

translate_left.xml

 

그 다음 res에 anim 폴더를 만든 뒤 레이아웃이 나타나고 사라질 때 사용할 애니메이션을 정의해준다.

translate_right과 translate_left는 각각 뷰를 오른쪽, 왼쪽으로 이동시키는 애니메이션이다.

 

이제 액티비티로 가서 기능을 구현해보자.

 

LinearLayout page;
Button button;

Animation translate_left;
Animation translate_right;

boolean isPageOpen = false;

먼저 전역변수로 나타날 레이아웃과 버튼, 애니메이션 객체를 만들어준다.

그리고 Sliding Page가 나타나있는지 여부를 저장할 boolean 변수도 만들어준다.

 

page = findViewById(R.id.page);
button = findViewById(R.id.button);

translate_left = AnimationUtils.loadAnimation(this, R.anim.translate_left);
translate_right = AnimationUtils.loadAnimation(this, R.anim.translate_right);

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if(isPageOpen){
            page.startAnimation(translate_right);
        } else {
            page.setVisibility(View.VISIBLE);
            page.startAnimation(translate_left);
        }
    }
});

onCreate에서는 먼저 레이아웃과 버튼을 찾아준 뒤, 애니메이션 파일을 불러와 준다.

그리고 버튼을 눌렀을 때 Sliding Page가 나타나 있으면 오른쪽으로 움직이는 애니메이션을 실행하고,

Sliding Page가 없다면 visibility를 visible로 바꾼 뒤 왼쪽으로 움직이는 애니메이션을 실행한다.

 

이제 오른쪽으로 Sliding Page가 이동한 뒤 visibility를 invisible로 변환해주어야 한다.

그러려면 애니메이션이 끝나는 시점을 알아야 하는데 이를 위해 AnimationListener를 구현해야 한다.

 

class SlidingAnimationListener implements Animation.AnimationListener {

    @Override
    public void onAnimationStart(Animation animation) {

    }

    @Override
    public void onAnimationEnd(Animation animation) {
        if(isPageOpen){
            page.setVisibility(View.INVISIBLE);
            button.setText("open");
            isPageOpen = false;
        } else {
            button.setText("close");
            isPageOpen = true;
        }
    }

    @Override
    public void onAnimationRepeat(Animation animation) {

    }
}

AnimationListener를 상속받아 클래스를 정의하려면 3개의 메소드를 정의해주어야 한다.

 

onAnimationStart()는 애니메이션 시작 시,

onAnimationEnd()는 애니메이션 종료 시,

onAnimationRepeat()는 애니메이션이 반복될 때 호출된다.

 

우리는 애니메이션이 종료될 때 visibility를 변환해주어야 하므로 onAnimationEnd()에 코드를 작성한다.

isPageOpen이 true면 visibility를 invisible로 바꾸고, button의 글자를 open으로 바꾸고, isPageOpen을 false로 바꾼다.

isPageOpne이 false면 visibility는 버튼 클릭 시 바꿨으므로 button과 isPageOpen만 바꿔준다.

 

SlidingAnimationListener listener = new SlidingAnimationListener();
translate_left.setAnimationListener(listener);
translate_right.setAnimationListener(listener);

마지막으로 listener 객체를 생성해 애니메이션에 지정해주면 된다.

 

 

버튼 클릭 시 정상적으로 레이아웃이 나타나고 사라지는 것을 볼 수 있다.

 

 

Reference

[부스트코스]안드로이드 프로그래밍

https://www.edwith.org/boostcourse-android

'Android > Concepts' 카테고리의 다른 글

Splash 화면 구현하기  (0) 2020.05.08
Animation 사용법  (0) 2020.05.07
Thread Animation 만들기  (0) 2020.05.07
RecyclerView 사용법  (0) 2020.05.04
MediaRecorder로 Audio 녹음하기  (2) 2020.05.04