티스토리 뷰

Android는 사용자가 화면을 전환했을 때, 보여줄 Layout을 각각 구분하여 처리할 수 있도록 해준다. 즉, 가로와 세로 Layout을 따로 저장해놨다가, 사용자가 화면을 전환했을 때 화면에 맞는 Layout을 불러와 처리한다.

 

Default 로 생성된 Layout이외에 화면이 가로로 전환되었을 때 사용할 Layout을 생성해주려면,

app/res/ 하단에 layout-land 라는 이름의 Resource directory를 추가하여 해당 디렉토리에 layout 디렉토리 내부에 Resource 파일들을 복사하여 사용하면 된다.

 

layout-land는 지정된 이름으로 앱을 실행했을 때, 단말 방향을 확인하여 가로인 경우 layout-land 폴더에서 Resource를 사용한다.

 

기본적으로 단말의 방향이 전환되는 경우, Android는 해당 Activity 객체를 중지 - 소멸 - 재생성 - 시작의 순서로 생명 주기를 가진다. 

 

Activity 객체가 소멸되고 다시 생성되는 과정에서 선언한 변수들을 static final이 아닌 이상 Activity 객체와 함께 소멸되었다가 재생성된다. 

 

그렇기 때문에, 해당 변수들을 단말이 전환될 때 다른 곳에 저장했다가 다시 복원하여 쓸 수 있도록 Android는 onSaveInstanceState() 메서드와 Bundle을 제공한다.

 

예제와 함께 알아보자.


◎app/res/layout.xml & app/res/layout-land.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    <EditText
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:inputType="textPersonName"
            android:ems="10"
            android:id="@+id/editTextTextPersonName"
            app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintVertical_bias="0.023"/>
    <Button
            android:text="저장"
            android:layout_width="128dp"
            android:layout_height="46dp" android:id="@+id/button"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            android:layout_marginBottom="300dp"
            android:background="#8F8F8F"
            app:layout_constraintTop_toBottomOf="@+id/editTextTextPersonName"
            app:layout_constraintHorizontal_bias="0.498" app:layout_constraintVertical_bias="0.0"
            android:layout_marginTop="70dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>


◎MainActivity.java

package com.example.sampleorientation;

import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    EditText editText;

    String name;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        showToast("onCreate 호출");

        editText = findViewById(R.id.editTextTextPersonName);

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

        button.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                name = editText.getText().toString();

                showToast("입력된 이름을 저장했습니다: " + name);
            }
        });

        if(savedInstanceState != null) {
            name = savedInstanceState.getString("name");
            showToast("값을 복원했습니다: " + name);
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putString("name", name);
    }

    protected void onStart() {
        super.onStart();
        showToast("onStart 호출");
    }

    protected void onStop() {
        super.onStop();
        showToast("onStop 호출");
    }

    protected void onDestroy() {
        super.onDestroy();
        showToast("onDestroy 호출");
    }

    public void showToast(String data) {
        Toast.makeText(this, data, Toast.LENGTH_LONG).show();
    }
}

화면 전환 시에 생명 주기를 확인하기 위해 onStart - onDestroy 메서드를 함께 넣어주었다.

 

실행해보면, 앞서 말했던 생명주기를 그대로 따라 메서드가 실행되는 걸 볼 수 있다.


앱을 한쪽 방향으로만 고정시키고 싶다면, AndroidManifest.xml 파일에서 아래와 같이 screenOrientation 속성 값을 지정하면 된다. 

 

◎AndroidManifest.xml

<activity android:name=".MainActivity"
          android:screenOrientation="landscape">
    
</activity>

 

Comments