Archives
Recent Posts
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
Today
Total
관리 메뉴

안드로이드 개발자의 창고

[51일차 Android] Screen Rotation(화면 회전 대응) 본문

Computer/Android

[51일차 Android] Screen Rotation(화면 회전 대응)

Wise-99 2023. 7. 19. 20:01

 

 

 

출처 : 안드로이드 앱스쿨 2기 윤재성 강사님 수업 PPT

 

 

 

📖 Screen Rotation

  • layout 폴더에 수식어를 추가하면 회전에 따른 화면을 따로 적용할 수 있다.
    • layout-port : 세로 화면
    • layout-land : 가로 화면

 

 

 

View 복원하기

  • 안드로이드에서 화면 회전이 발생하면 화면을 새롭게 만들게 되는데 일부 UI 요소들은 초기 값으로 설정되기 때문에 복원하는 작업을 해야 한다.
  • onSaveInstanceState 메서드에서 복원 시 필요한 값을 저장한다.
  • onCreate 메서드에서 복원 작업을 해준다.

 

 

 

화면 회전 막기

  • 화면이 회전되는 것을 막고자 한다면 AndroidManifest.xml의 Activity 태그에 screenOrientation 속성으로 설정하면 된다.

 

 

 

예제 코드

layout 파일 추가

  • Available qualifiers - orientation을 추가하여 설정해준다.
    • Portrait : 세로 화면
    • Landscape : 가로 화면
    • Square : 정사각형 화면

 

 

 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    android:padding="10dp"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="아이디"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

    <EditText
        android:id="@+id/editTextUserId"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:ems="10"
        android:inputType="text"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="비밀번호"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

    <EditText
        android:id="@+id/editTextUserPw"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:ems="10"
        android:inputType="textPassword"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

    <Button
        android:id="@+id/buttonLoginSubmit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="로그인"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

    <Button
        android:id="@+id/buttonJoin"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="회원가입"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

    <TextView
        android:id="@+id/textViewResult"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />
</LinearLayout>

 

 

 

activity_main.xml(land)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="10dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/textView3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="아이디"
            android:textAppearance="@style/TextAppearance.AppCompat.Large" />

        <EditText
            android:id="@+id/editTextUserId"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:ems="10"
            android:inputType="text"
            android:textAppearance="@style/TextAppearance.AppCompat.Large" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/textView4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="비밀번호"
            android:textAppearance="@style/TextAppearance.AppCompat.Large" />

        <EditText
            android:id="@+id/editTextUserPw"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:ems="10"
            android:inputType="textPassword"
            android:textAppearance="@style/TextAppearance.AppCompat.Large" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:orientation="horizontal">

        <Button
            android:id="@+id/buttonLoginSubmit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="로그인" />

        <Button
            android:id="@+id/buttonJoin"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="회원가입" />

    </LinearLayout>

    <TextView
        android:id="@+id/textViewResult"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

</LinearLayout>

 

 

 

MainActivity.kt

class MainActivity : AppCompatActivity() {

    lateinit var activityMainBinding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Toast.makeText(this, "${savedInstanceState}", Toast.LENGTH_LONG)

        activityMainBinding = ActivityMainBinding.inflate(layoutInflater)

        activityMainBinding.run {

            // savedInstanceState에 저장된 데이터가 있다면 복원
            if(savedInstanceState != null){
                val str1 = savedInstanceState.getString("str1")
                textViewResult.text = str1
            }

            buttonLoginSubmit.setOnClickListener {
                editTextUserId.setText("하하하하")
                editTextUserPw.setText("aaaaa")
            }

            buttonJoin.setOnClickListener {
                textViewResult.text = "버튼을 눌렀습니다"
            }
        }

        setContentView(activityMainBinding.root)
    }

    // 화면 회전이 발생했을 때 호출되는 메서드(프래그먼트도 동일)
    // 매개변수로 들어오는 번들 객체는 화면이 다시 만들어지고 onCreate 메서드를 호출할 때 매개변수로 전달된다.
    // 여기에는 화면 회전 후 값이 유지되지 않는 View들에 대한 복원 작업을 할 수 있도록 데이터를 저장하는 역할을 한다.
    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)

        // 새로운 화면에서 복원해야 할 뷰의 값을 지정한다.
        outState.putString("str1", activityMainBinding.textViewResult.text.toString())
    }
}

 

 

 

결과

  • textViewResult의 text가 그대로 유지되는 듯한 결과
  • 내부 동작은 화면이 회전될 때마다 화면이 새롭게 만들어지면서 Bundle에 저장한 데이터를 다시 복원하는 것이다.