본문 바로가기
ANDROID/Android 앱 프로그래밍

[Android] 레이아웃 인플레이션 (layout inflation)

by 주 녕 2021. 5. 18.
728x90

모든 내용은 Do it! 안드로이드 앱 프로그래밍을 바탕으로 정리한 것입니다. 

 

레이아웃 인플레이션

안드로이드 앱을 개발할 때, 우리는 2가지 파일에 나누어서 개발함.

  • 화면 배치를 알려주는 XML 레이아웃 파일
  • 화면의 기능을 담당하는 소스 코드 파일

코드를 2개의 파일로 분리하는 이유는  용도에 따른 코드 분리로 관리가 수월해지기 때문임

그렇다면 이 2개의 파일은 어떻게 연결되는 것인가?

 

setContentView() 메서드

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}
  • AppCompatActivity에는 화면에 필요한 메서드들이 들어있음
    • 그 중에 하나가 setContentView() 메서드
    • setContentView() 메서드에 XML 레이아웃 파일 이름을 파라미터로 전달하여 XML 레이아웃과 소스 코드 연결
    • R.layout.레이아웃파일명 (app/res/layout)

 

앱이 실행될 때 XML 레이아웃의 내용이 메모리에 객체화되고 객체화된 XML 레이아웃을 소스파일에서 사용함

즉, XML 레이아웃의 내용이 메모리에 객체화 되는 과정이 '인플레이션(inflation)'

 

XML 레이아웃은 앱이 실행되는 시점에 메모리에 객체화됨

→ XML 레이아웃 파일에 <Button>을 정의해도 앱은 자신이 실행되기 전까지 버튼이 있는지 모름

→ setContentView() 메서드 실행 전에 <Button>을 참조한다면 NullPointerException 발생

 

∴ setContentView() 메서드가 하는 일은 2가지

→ 메서드로 전달할 수 있는 파라미터는 View 객체 or XML 리소스

  1. 화면에 나타낼 View를 지정
  2. 레이아웃 내용을 메모리에 객체화

 


 

BUT, setContentView() 메서드는 액티비티의 화면 전체(메인 레이아웃)를 설정하는 역할 만을 수행함.

→ setContentView() 메서드는 부분 화면(부분 레이아웃)을 메모리에 객체화할 수는 없음

→ 부분 화면을 메모리에 객체화 하려면? 인플레이터 사용

→ 안드로이드 시스템 서비스로 LayoutInflater 클래스 제공

 

  1. 메인 레이아웃은 setContentView(R.layout.activity_main)으로 객체화 하여 화면에 나타냄
  2. 일부 화면을 분리한 화면(sub1.xml)은 LayoutInflater 객체를 사용해 ViewGroup으로 객체화(인플레이션)한 후 메인 레이아웃에 추가

 

public class MainActivity extends AppCompatActivity {

    LinearLayout container;

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

        container = findViewById(R.id.container);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                inflater.inflate(R.layout.sub1, container, true);
                CheckBox checkBox = container.findViewById(R.id.checkbox);
                checkBox.setText("로딩 완료");
            }
        });
    }
}
  • main 액티비티의 버튼을 연결하고, setOnClickListener로 클릭 리스터를 연결함
  • getSystemService() 메서드를 사용해 LayoutInflater 객체를 참조함
  • 참조한 inflater의 inflate() 메서드의 파라미터로 R.layout.sub1(XML 레이아웃 리소스)과 container 객체(부모 컨테이너)를 전달
    • container를 id로 갖는 리니어 레이아웃 객체에 sub1.xml 파일의 레이아웃을 설정하는 것
    • 이 과정을 통해 부분 레이아웃(sub1.xml)에 정의된 뷰들이 메모리에 로딩되며 객체화 과정을 거침

결과화면

728x90

댓글