XML 레이아웃과 소스 코드 매칭
화면 배치를 담당하는 레이아웃은 소스 코드와 분리시키면 좀 더 쉽게 사용할 수 있습니다.
특히 소스 코드를 이해하기 힘든 일반 사람이나 디자이너라고 하더라도 XML 파일을 어떻게 만드는지만 알면 화면 레이아웃을 만들 수 있다는 장점이 있습니다.
그런데 이렇게 분리된 XML 파일의 내용을 소스 코드에서 어떻게 인식할 수 있을까요?
예를 들어, XML 레이아웃에 버튼을 넣어두었다면 이 버튼을 소스 코드에서도 사용할 수 있어야 하는데 어떤 과정을 거쳐서 인식하게 되는 것일까요?
프로젝트를 만들면 첫 화면을 위한 XML 레이아웃과 소스 파일이 자동으로 만들어집니다.
activity_main.xml 파일과 MainActivity.java 파일이 그것인데요.
이 소스 코드에서 XML 레이아웃 파일을 이해하려면 setContentView 메소드의 파라미터로 해당 XML 레이아웃 파일을 지정해주어야 합니다.
activity_main.xml 파일이 layout 폴더 안에 들어있으니 R.layout.activity_main 을 전달해주어야 하는 거죠.
그렇게 하면 내부적으로 인플레이션 과정이 진행됩니다.
XML 레이아웃 파일 안에 들어있는 뷰 태그들을 이용해 뷰 객체를 메모리에 만드는 과정이 인플레이션 과정입니다.
이렇게 XML 레이아웃 파일의 내용이 메모리에 객체로 만들어지면 소스 코드에서는 그 객체들을 찾아 사용할 수 있습니다.
객체를 찾을 때는 findViewById 메소드를 이용할 수 있으며 XML 레이아웃에 뷰를 추가할 때 넣어둔 id 속성의 값을 파라미터로 사용합니다.
Button button = (Button) findViewById(R.id.startButton);
이 코드는 지금까지 많이 사용해봤으니 어렵지 않죠?
뷰를 위한 레이아웃 인플레이터
화면 전체를 나타내는 액티비티의 경우에는 setContentView 메소드를 이용해 XML 레이아웃을 인플레이션할 수 있는데, 엑티비티 레이아웃XML 파일 안에 포함되지 않는 뷰의 경우에는 setContentView 메소드를 통해 인플레이션되지 않습니다.
setContentView 메소드는 액티비티를 위해 만들어 놓은 것이기 때문에 뷰를 위한 인플레이션에는 사용할 수 없는 거죠.
실제로 액티비티와 뷰가 내부적으로 관리되는 방식이 달라서 그런 것인데, 이 때문에 뷰의 경우에는 직접 인플레이션을 해야 합니다.
버튼과 같은 뷰는 화면 레이아웃이 필요하지 않지만 레이아웃을 상속해서 만든 뷰는 화면 배치가 필요하기 때문에 XML 레이아웃을 만들고 그 레이아웃을 소스 파일에 설정하게 됩니다.
레이아웃 인플레이터 객체는 시스템 서비스 객체로 제공되기 때문에 getSystemService 메소드를 이용해 참조할 수 있습니다.
getSystemService(Context.LAYOUT_INFLATER_SERVICE)
그리고 뷰 객체가 있으면 그 뷰 객체에 인플레이션한 결과물을 설정하게 됩니다.
리니어 레이아웃 객체이거나 리니어 레이아웃을 상속한 뷰 객체가 container라는 이름으로 만들어져 있다면 다음과 같은 코드를 이용해 레이아웃 인플레이션을 진행할 수 있습니다.
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.sub1, container, true);
XML 레이아웃의 이름은 sub1.xml로 만들어져 있고 이 XML 레이아웃에 들어가 있는 뷰들은 메모리에 객체로 만들어진 후에 container 뷰 객체에 설정됩니다.
이런 방식은 새로운 뷰를 정의할 때 자주 볼 수 있는데, 동적으로 레이아웃이 변경, 추가되는 경우에도 사용됩니다.
최근댓글