티스토리 뷰

안드로이드

안드로이드 - 뷰 펼치고 닫기(응용)

쉬엄쉬엄하자 2020. 2. 13. 14:45
728x90

안녕하세요. 이번에는 저번에 뷰를 눌렀을 때 위로 펼치고 닫는 기능을 구현하는 방법에 대해 알아 보았습니다. 

https://game-happy-world.tistory.com/10

 

안드로이드 - 뷰 펼치고 닫기(ObjectAnim)

0. 안드로이드 앱을 개발하던중 리스트뷰가 있는 리니어레이아웃을 숨겨놨다가 버튼을 누르면 위로 들어나고 다시 버튼을 누르면 원래상태로 들어가도록 하는 디자인을 필요로 하였습니다. 근데 생각보다 순탄치가..

game-happy-world.tistory.com

위 글처럼 구현하면 정상적으로 구현이 되겠지만 만약 정식적인 배포를 위한 앱을 개발중이라면 이전 글에서 소개한 방법 그대로 구현하면 안됩니다.

왜냐하면 이 세상에는 다양한 디바이스가 존재하고 모두 다른 해상도와 화면을 가지고 있기 때문이죠.

따라서 정적인 고정된 크기로 애니메이션을 구현하면 테스트기기에서는 정상적으로 동작하는것처럼 보일 수 있겠지만 어떤 사람에게는 뷰가 너무 위로 올라가거나 너무 덜 올라가는 경우가 생깁니다.

따라서 이번에는 여러 사용자들에게 동일한 결과를 보여주기위한 뷰 애니메이션 구현 방법에 대해 알아보겠습니다.

 

일단 메인액티비티의 xml의 코드부터 보겠습니다.

<activity_main.xml>

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    android:paddingStart="12dp"
    android:paddingEnd="12dp"
    tools:context=".MainActivity">

    <LinearLayout
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:orientation="vertical"
        android:id="@+id/maincontent"
        android:layout_width="match_parent"
        android:background="@color/colorPrimary"
        android:layout_height="match_parent">

    </LinearLayout>
    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:orientation="horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintGuide_percent="0.9">

    </androidx.constraintlayout.widget.Guideline>

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline2"
        android:layout_width="wrap_content"
        android:orientation="horizontal"
        android:layout_height="wrap_content"
        app:layout_constraintGuide_percent="1.8">

    </androidx.constraintlayout.widget.Guideline>

    <LinearLayout
        android:id="@+id/drawview"
        android:orientation="vertical"
        android:background="@color/colorAccent"
        app:layout_constraintTop_toBottomOf="@id/guideline"
        app:layout_constraintBottom_toTopOf="@id/guideline2"
        android:layout_width="match_parent"
        android:layout_height="0dp">
        <Button
            android:layout_marginTop="12dp"
            android:layout_gravity="center"
            android:background="@color/colorPrimary"
            android:layout_weight="20"
            android:id="@+id/drawer"
            android:layout_width="100dp"
            android:layout_height="match_parent">

        </Button>

        <LinearLayout
            android:layout_weight="1"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

        </LinearLayout>

    </LinearLayout>


</androidx.constraintlayout.widget.ConstraintLayout>

 

여기서 중요한 점은 constraint레이아웃을 사용하는것입니다. 리니어레이아웃에서도 weight를 활용하여 모든 사용자에게 동일한 화면을 제공할 수 있도록 비율을 맞출 수 있지만 안드로이드 표준에서는 최상위 레이아웃으로 constraint 사용을 권장하고 있습니다.

그리고 다음으로 중요한것은 guideline을 사용하는것입니다. 이를 사용하면 원하는 적절한 비율에 레이아웃을 배치할 수 있습니다. 저는 애니메이션을 적용시킬 대상을 화면의 아래 0.9부터 시작하여 화면밖의 1.8까지 크기를 갖도록 배치하였습니다. 이제 메인액티비티에서 애니메이션을 구현해보겠습니다.

 

<MainActivity.java>

package c.guitar.listviewexample;

import androidx.appcompat.app.AppCompatActivity;

import android.animation.ObjectAnimator;
import android.graphics.Point;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    Button drawer;
    View drawtarget;
    boolean toggle;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        drawer = findViewById(R.id.drawer);
        drawtarget = findViewById(R.id.drawview);

        drawer.setOnClickListener(new Button.OnClickListener(){
            @Override
            public void onClick(View v){
                if(toggle == false){
                    Display display = getWindowManager().getDefaultDisplay();
                    Point size = new Point();
                    display.getSize(size);
                    int height = size.y;
                    Log.d("_test", ""+height);
                    ObjectAnimator anim = ObjectAnimator.ofFloat(drawtarget, "translationY", -height*0.7f);
                    anim.setDuration(500);
                    anim.start();
                }
                else{
                    ObjectAnimator anim = ObjectAnimator.ofFloat(drawtarget, "translationY", 0);
                    anim.setDuration(500);
                    anim.start();
                }
                toggle = !toggle;
            }
        });
    }
}

애니메이션을 실행시킬 트리거가 될 버튼에 onClick메서드를 구현합니다. 여기서 중요한점은 Display클래스를 사용하여 현재 디바이스의 화면 크기를 구해오고 이의 비율만큼 애니메이션을 움직이는것입니다. 이전 글에서는 정적으로 -1200으로 정적인 크기만큼 애니메이션을 적용시켰지만 이와 같이 구현한다면 모든 기기에서 동일한 크기로 동작합니다.

 

이상 모든 화면에서 똑같이 동작하는 뷰 펼치고 닫는 애니메이션을 구현하는 방법에 대해 알아보았습니다.

댓글