JLOG

[안드로이드 스튜디오 강좌 #15] 이벤트 처리 이해하기 - 단말 방향 전환 이벤트 처리 본문

안드로이드 스튜디오/Do it 안드로이드 스튜디오

[안드로이드 스튜디오 강좌 #15] 이벤트 처리 이해하기 - 단말 방향 전환 이벤트 처리

정정선선 2020. 5. 19. 04:37

! 목표

단말 방향을 전환 했을 때 화면 방향이 가로, 세로로 전환되는 이벤트를 알아보자

 

 

1. 단말 방향 변경

단말을 가로/세로 방향으로 바꿨을 때 가로 세로의 화면 비율에 따라 화면이 다르게 보여야 한다.

단말 방향이 전환 되었을 때 화면이 다르게 나타나게 하기 위해 XML 레이아웃을 따로 만들어야 한다.

 

 

실습하기 위해 SampleOrientation 프로젝트를 생성해주자

 

res 폴더 아래에 새 폴더를 만들어주자

res 폴더 클릭 - 마우스 우클릭 - New - Android Resource Directory

Directory Namelayout-land를 입력하고 OK를 누르면 폴더가 생성된다.

 

 

하지만 새로 만든 폴더는 프로젝트 창에 보이지 않는다.

프로젝트 창에서는 필요한 정보만을 정리해 보여주기 때문이다.

 

새로 만든 폴더를 확인하려면 상단에서 [Project] 탭을 선택해 SampleOrientation/app/src/main/res 경로로 들어가면 확인할 수 있다.

 

 

 

단말이 가로방향으로 보일 때 layout-land 폴더 안에 있는 XML 레이아웃 파일이 사용 된다.

activity_main.xml을 열어 텍스트뷰의 내용을 '세로', textSize를 '30sp'로 변경해주자

이 activity_main.xml 폴더를 복사해서 layout-land 폴더 안에 붙여넣자.

가로 방향으로 activity_main.xml의 복사된 것을 확인할 수 있다.

layout-land안의 activity_main.xml의 textView 내용을 '가로'로 변경하자.

 

 

 

 

단말의 방향이 바뀔때 액티비티를 메모리에서 없앴다가 다시 생성한다.

이것을 확인해보자

 

MainActivity.java 파일을 열고 MainActivity 클래스를 클릭하고 마우스 우클릭 - Generate-Override Methods 메뉴를 눌러 onStart, onStop, onDestroy를 선택한 후 OK를 누른다.

 

각각 메서드가 추가 되면 아래 코드를 추가로 작성해보자

public class MainActivity extends AppCompatActivity {

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

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

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

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

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

 

onCreate(), onStart(), onStop(), onDestroy()가 호출될 때마다 토스트 메세지로 확인이 가능하다.

 

실행시켜보면, 단말의 방향을 바꿨을 때 레이아웃이 달라지고 액티비티가 새로 만들어지는 것을 알 수 있다.

 

 

 

단말의 회전은 오른쪽의 회전 버튼을 누르고 단말 화면 안에 있는 작은 회전 버튼을 한번 더 눌러야지만 단말 자체에 회전이 된다.

 

 

 

 

단말의 방향을 바꿀 때마다 액티비티를 없앴다, 새로 생성하기 때문에 액티비티 안에 선언해 두었던 변수 값이 사라지므로 변수의 값을 저장했다가 다시 복원하는 방법이 있어야 한다.

 

onSaveInstanceState 콜백 메서드를 이용해 액티비티가 종료되기 전의 상태를 저장한다. 이때 저장한 상태는 onCreate() 메서드가 호출되는 번들 객체로 복원할 수 있다.

 

상태를 복원하는 기능을 확인하기 위해 2개의 각각 activity_main.xml 안에 에디트 텍스트(Plain Text)와 버튼(Button)을 추가한다.

단, 각각의 xml 파일의 에디트 텍스트와 버튼의 아이디는 동일해야 한다.

 

에디트텍스트에 글자를 넣고 버튼을 누르면 MainActivity 클래스 안에 정의한 변수에 해당 글자를 할당할 것이다.

해당 사진처럼 설정해보자.

 

MainActivity.java 폴더를 열어서 onSaveInstanceState() 메서드를 정의한다.

MainActivity.java 파일을 열고 MainActivity 클래스를 클릭하고 마우스 우클릭 - Generate-Override Methods 메뉴를 눌러 onSaveInstanceState()를 선택하고 OK 버튼을 눌러준다.

 

 

아래의 코드 대로 입력해주자

public class MainActivity extends AppCompatActivity {
    String context;
    EditText editText;

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

        editText = findViewById(R.id.editText);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener(){
            public void onClick(View view){
                context = editText.getText().toString(); 
								// 버튼을 클릭했을 때 사용자가 입력한 값을 context 변수에 할당
                showToast("입력된 값을 변수에 저장했습니다 : " + context);
            }
        });

        if (savedInstanceState != null) { // 화면이 초기화 될때 context 변수의 값 복원
            context = savedInstanceState.getString("context");
            showToast("값을 복원했습니다 : "+context);
        }
    }

//중략 ...

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

        outState.putString("context", context); //context 변수의 값 저장
    }

 

실행해보면 가로에서 입력한 내용도 세로 방향으로 바뀌어도 유지가 되는 것을 확인할 수 있다.

 

 

 

 

2. 액티비티를 유지하며 레이아웃 변경

지금까지 단말 방향이 바뀌어 액티비티가 새로 만들어질때 변수의 값을 저장했다가 복원하는 방법을 알아보았다.

하지만 액티비티를 바꾸지 않고 화면에 보이는 레이아웃만 바꾸고 싶다면 액티비티를 없앴다가 다시 만들 필요가 없다.

액티비티를 유지하며 레이아웃을 변경하는 방법을 알아보자

 

단말의 방향이 바뀌는 것을 앱에서 이벤트로 전달받도록 하고 액티비티는 그대로 유지하는 방법을 사용하려면 먼저 매니페스트에 액티비티를 등록할 때 configChanges 속성을 설정해야한다.

 

 

 

-실습

새 SampleOrientation2 프로젝트를 생성하자

actvitiy_main.xml의 textView의 text를 '단말의 방향을 바꾸어보세요.'로 변경하고 글자 크기는 30sp로 설정해주자.

왼쪽 프로젝트 창에서 /app/manifests 폴더 안에 있는 AndroidManifest.xml 파일을 열어 아래의 코드를 입력해주자

 

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.techtowm.sampleorientation2">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity"
            android:configChanges="orientation|screenSize|keyboardHidden"
            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

코드 설명

        <activity android:name=".MainActivity"
            android:configChanges="orientation|screenSize|keyboardHidden"
            >

방향 전환을 알 수 있도록 configChanges 속성을 설정했다.

android:configChanges="orientation|screenSize|keyboardHidden"을 통해 화면방향이 전환되어도 액티비티를 초기화하지 않는다.

 

단말의 방향이 바뀔 때마다 액티비티에서 인식할 수 있으며, configurationCanged() 자동으로 호출이 된다.

 

keyboardHidden 값은 단말의 방향 전환과는 관련이 없지만, 액티비티가 보일 때 키패드가 자동으로 나타나지 않도로 하고 키패드가 보여야 할 시점을 액티비티 쪽에 알려준다.

 

 

MainActivity.java에 아래 코드들도 입력해보자

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void onConfigurationChanged(Configuration newConfig){
        super.onConfigurationChanged(newConfig);

        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE){
            showToast("방향: ORIENTATION_LANDSCAPE");
        }
        else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
            showToast("방향: ORIENTATION_PORTRAIT");
        }
    }

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

참고로 MainActivity 클래스를 클릭하고 Ctrl+O를 누르면 쉽게 메서드를 호출할 수 있다.

 

과를 단말의 방향이 바뀔 때마다 orientation 속성을 통해서 단말이 방향이 가로인지 로인지 확인할 수 있다. 이 값을 비교해서 토스트 메세지를 띄우는 코드이다.

 

실행시켜서 확인해 보면 방향 전환이 될 때마다 Toast 메세지가 출력 되는 것을 확인할 수 있다.

 

 

 

 

3. 화면 방향 고정

방향을 세로 또는 가로로 고정시키고 싶으면 AndroidManifest.xml 파일에서 액티비티의 screenOrientation 속성값을 지정하면된다.

activity 태그 안에 아래의 코드를 추가하면 된다.

android:screenOrientation="portrait"  // 세로로 고정
android:screenOrientation="landscape" // 가로로 고정

 

 

 

 

 

 

## 이 글은 Do it 안드로이드 앱 프로그래밍을 참고해서 작성되었습니다.

도서에는 더 자세하고 알기 쉽게 설명이 되어 있어 도서를 참고하면서 공부하는 것을 추천드립니다.

도서 정보 : http://www.yes24.com/Product/Goods/15789466

 

Do it! 안드로이드 앱 프로그래밍

안드로이드 분야 1위 도서, 개정 2판으로 돌아오다! (롤리팝, 안드로이드 스튜디오)안드로이드 분야에서 큰 사랑을 받아온 [Do it! 안드로이드 앱 프로그래밍]의 두 번째 전면 개정판이 나왔다. 최신 롤리팝 버전을 적용한 이번 개정 2판은 지난 젤리빈 개정판보다 더 개정폭이 커졌다. 특히 2014년 12월 발표된 안드로이드 공식 개발 도구인 ‘안드...

www.yes24.com

유투브 강의 : https://www.youtube.com/watch?v=nN4xnEcnjE8

Comments