듀다의 성장개발로그

[부스트코스] 안드로이드 프로그래밍 10 - 인플레이션 본문

안드로이드/부스트코스

[부스트코스] 안드로이드 프로그래밍 10 - 인플레이션

du-da 2020. 2. 14. 12:34

오늘은 좀더 이론적인 내용을 다뤄보도록 하겠습니다. 인플레이션이라는 개념입니다.

 

하나의 액티비티는 레이아웃 파일(xml)과 소스 코드 파일(java)로 구성되는데요, 두 개의 파일이 쌍으로 이루어집니다.

그런데 이 파일들의 내용을 자세히 보면, 화면 레이아웃 상에 어떤 위젯이 존재한다고 하더라도

xml파일에 그 위젯의 정보만 있을 뿐, 생성해주는 코드는 존재하지 않는 경우가 있습니다.

화면에 표시된다는 건 객체화되어 메모리 어딘가에 올라가있다는 것인데 그러면 이 위젯은 누가, 언제 생성하여 메모리에 할당시킬까요?

 

레이아웃에 추가된 버튼을 객체화하여 메모리 공간을 할당하는 것은 시스템의 역할입니다.

이 과정을 바로 인플레이션이라고 하는데요, MainActivity.java 파일에 기본으로 존재하는 이 setContentView 메소드가 호출될 때 위젯이 객체화됩니다.

또한 레이아웃 파일(xml)과 소스 코드 파일(java)을 연결하여 화면에 나타낼 뷰를 지정하는 역할도 수행합니다.

 

그런데 시스템이 인플레이션을 수행했기 때문에, 안드로이드 스튜디오는 이 위젯이 메모리의 어디에 할당되었는지 알 수 없습니다. 터치 등 어떤 동작을 수행하기 위해선 찾아줘야겠죠? 아이디를 통해서 찾을 수 있습니다. 뷰를 아이디를 통해 접근하는 메소드가 바로 ViewById입니다.

그래서 setContentView보다 ViewById가 먼저 나오면 에러가 발생합니다.

객체화하여 메모리에 할당하는 setContentView가 없으면

선언되지도 않은 버튼에 동작을 실행하고 하게 되기 때문이죠.

 

그런데 버튼 등의 위젯이 아닌 레이아웃은 setContentView로 인플레이션을 수행할 수 없습니다.

예를 들면 부분 화면이 배치되었을 때가 이런 경우에 포함됩니다. 좀 더 구체적으로 설명하면 xml파일을 새로 만들어 레이아웃을 구성하고, 그 레이아웃을 activity_main의 다른 레이아웃 안에 표시하려는 경우가 바로 이러한 경우가 될 수 있습니다. 이 때는 activity_main 안의 레이아웃에 들어간, 새로 생성된 xml의 화면이 부분 화면이 됩니다.

 

이렇게 부분화면이 구성되었을 때는 직접 인플레이션을 수행해야 합니다. 인플레이션은 그것을 수행하는 LayoutInflater를 선언하고 실제로 인플레이션을 실행시키는 inflate메소드를 호출하여 수행할 수 있습니다.

 

예를 들어 볼까요? 화면에 어떤 버튼 하나와 container라는 이름의 프레임 레이아웃 하나를 추가하고, 버튼을 누르면 프레임 레이아웃에 부분 화면이 표시되게 하고 싶다면

 

MainActivity클래스에서 FrameLayout container를 선언하고

onCreate에서 findViewById로 container와 버튼을 정의합니다.

 

버튼을 클릭할 때 화면이 변하도록 만들어야 하니 이벤트 처리를 합니다.

버튼의 setOnClickListener 메소드를 호출하고, 파라미터로 OnClickListener를 생성해 넣습니다. 
그리고 OnClickListener의 오버라이드된 onClick에 인플레이터를 선언하고, inflate메소드를 호출합니다.

그러면 성공적으로 인플레이션을 성공적으로 수행할 수 있습니다.

 

inflate 메소드에는 파라미터로 부분 화면 xml, 부분 화면이 들어간 레이아웃, 부분화면 표시 여부가 들어갑니다.
즉, 어떤 것을 객체화할지 뿐 아니라 어디에 붙여줄지도 정할 수 있습니다.

 

  1. XML 레이아웃에 LinearLayout 태그를 넣었을 때 이 객체에 새로 만든 XML 레이아웃을 적용하려면 어떻게 해야 할까요?

    - 제가 질문을 잘 이해한 건지 모르겠네요. 하나의 레이아웃으로 LinearLayout이 들어간 레이아웃을 채우고, 하나의 레이아웃이 새로 만든 XML 레이아웃을 배경으로 하도록 인플레이션을 해주면 될 것 같습니다. 

  2. LinearLayout을 상속해서 새로운 클래스를 정의하고 이 클래스에서 새로운 객체를 만들었다면 이 객체에 새로 만든 XML 레이아웃을 어떻게 적용할 수 있을까요?

    - 새로 만든 XML레이아웃을 새로운 객체에 지정해서 인플레이션을 해주면 될 것 같습니다.