Develop

[android] 화면 전환(가로/세로)시 설정

by hooni posted Apr 23, 2013
?

단축키

Prev이전 문서

Next다음 문서

ESC닫기

크게 작게 위로 아래로 댓글로 가기 인쇄

여기서 화면 회전이란

1. 실제 장치의 회전으로 인해 가로보기 <-> 세로보기 전환이 되는 경우

2. 슬라이드 키보드(하드웨어)를 열고 닫을 때 가로보기 <-> 세로보기 전환이 되는 경우

크게 두가지로 나눌 수 있겠습니다.


안드로이드의 경우 화면 회전에 따라 View의 위치 및 크기를 재계산 하고(onMeasure()) 다시 그려줍니다.(onDraw())  별로의 설정이나 구현 없이요.


그래서 WebView 하나 덩그라니 놓아둔 Activiy도 별 문제 없이 다음과 같이 화면 회전이 됩니다.


이제, 네이버에 로그인을 한 번 해볼까요?


오. 이런. 저는 세로보기 상태의 Virtual Keyboard는 싫어합니다.

좀 더 터치하기 편하게 옆으로 돌려보죠. 

(혹은 슬라이드 형태의 쿼티 키보드가 있다면 슬라이드 하겠죠?)


...맙소사. 처음 Activity가 Start 되었을 때의 Url로 돌아왔습니다. 저는 이 현상을 체험했을 때 현기증으로 쓰러지는 줄 알았습니다.


정확히는 Url이 돌아온 게 아니라, 화면을 회전했을 뿐인데 해당 Activity는 onDestroy()를 거쳐 onCreate()를 다시 실행합니다. .....제정신입니까? 

(아, 물론 제 착각이었습니다. 제정신인건 알고 있어요. 미안해요.)


곧 해결법을 찾아보기로 하였습니다.

Activity에 onRetainNonConfigurationInstance() 가 있더군요!


1. Configuration이 변경 될 때 onRetainNonConfigurationInstance()가 호출 되고, 여기에서 넘겨줄 Object를 설정. 뭐, Url String정도 넘겨 줄까요?


2. onCreate에서 앞서 넘겨준 Object를 getLastNonConfigurationInstance()로 받아서 loadUrl... 물론 getLastNonConfigurationInstance()에서 아무 값도 반환 되지 않는다면 화면 회전이 아니라 처음 Activity가 start했다는 뜻이니 예외 처리를 잘 해줍시다.


이런. 이렇게 해두고 보니 문제가 있습니다. Url만 띄운다고 되는 게 아니거든요. 화면에 입력중인 값, 웹페이지의 자바스크립트에서 가지고 있는 값... 그래서 그냥 WebView 자체를 넘겨줬습니다. getLastNonConfigurationInstance()를 통해 WebView를 받아서 addChild() 해주는 편법을 썼죠. 주의할점은 View는 하나의 Parent만 가질 수 있으므로, onRetainNonConfigurationInstance()에서 WebView를 Parent에서 remove 해줘야 합니다. 


결과는 만족스러웠습니다. 그리고 아예 Object를 넘겨줄 때 HashMap으로 넘겨서 WebView와 필요한 몇 가지 변수들의 값을 추가로 넘겨줬습니다. 음. 잘 동작하는군. 화면이 좀 깜박여 보인다는 것을 제외한다면...

넘겨줘야하는 변수가 엄청나게 늘어난다고 해도 수고만 조금 더 들어갈 뿐, 별 문제는 없어 보입니다. Intent처럼 제한 없이 Object를 넘겨 줄 수 있으니까요.


...여기까지, 코드 없이 설명만 읽기에 괴로우셨을 겁니다. 코드 몇 줄이면 될 것을 이런 게으름뱅이!

하지만 말로 설명하는 게 더 귀찮아요. 코드를 쓰지 않은 것은 일부러 그런 겁니다. 

이건 잘못된 방법이거든요.

이런식으로 구현한 경우를 몇 번 본적이 있어서 무심코 따라했는데, 이 포스팅을 보시는 분들은 따라하지 않도록 주의하시길 바랍니다. 100%의 경우라고는 말 못하지만 대부분의 경우는 위와 같이 하는 게 헛수고일 것입니다.


제대로 된 해결법은 다음과 같습니다.


1. AndroidManifest.xml 파일을 열어줍시다.

2. Activity에 다음 Attribute를 추가해 줍니다. 


  android:configChanges="orientation|keyboard"


Activiti가 10개라면 각각 전부 다 추가해 주시면 됩니다. 아, 물론 적용하고 싶은 Activity들이요. -끝-


이렇게 하면 Activity가 재생성 되지 않습니다. 넵. Object따위 넘겨줄 필요 없습니다. 따로 구현 할 필요가 없다는 뜻입니다. 추가로, onRetainNonConfigurationInstance() 이후 정상적으로 onConfigurationChanged()가 호출 되고요.

물론 각 View들도 정상적으로 onMeasure()후 onDraw() 됩니다.



자세한 사항은 다음 문서를 참고하시기 바랍니다.

[출처] http://developer.android.com/guide/topics/manifest/activity-element.html#config