티스토리 뷰

지금까지의 다룬 예제들은 1개의 activity_main.xml 레이아웃을 MainActivity.java가 어플리케이션을 실행하면서, onCreate() 메서드 내부에 호출해놓은 setContentView() 메서드를 사용하여 res 하위에 있는 activity_main.xml을 호출하여 화면에 보여주었다고 이해할 수 있다.

 

즉, setContentView(R.layout.activity_main);을 호출하여 레이아웃 파일을 객체화하여 사용한다는 것이다. 하지만, setContentView() 메서드는 Activity의 전체 화면(메인 레이아웃)을 설정하는 역할만을 수행한다. 부분 레이아웃을 만들어 화면 한 부분에 띄우려고 할 때에는 사용이 불가능하다는 이야기이다.

 

이럴 때 부분 레이아웃을 객체화하기 위하여 사용하는 것이 바로 인플레이터이다. Android는 이를 위해 시스템 서비스로 LayoutInflater 클래스를 제공한다. LayoutInflater를 사용하기 위해서는 getSystemService 메서드로  SystemService객체를 호출하여 사용한다는 것인데, 이 System Service는 단말이 시작되면서 항상 실행되는 서비스이며, 나중에 자세히 다뤄보도록 하겠다.

 

우선, 1개의 메인 레이아웃 위에 버튼을 클릭하여 부분 레이아웃을 띄우는 간단한 예제를 확인해보자.


◎activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity" android:orientation="vertical">
    <TextView
            android:text="버튼을 눌러 화면을 추가하세요"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" android:id="@+id/textView"
            android:textSize="20sp"
    />
    <Button
            android:text="추가하기"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" android:id="@+id/button"/>
    <LinearLayout
            android:id="@+id/container"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    </LinearLayout>
</LinearLayout>

이후 동일한 디렉토리에 sub1.xml이라는 부분 레이아웃 파일을 생성한다.

 

◎res/layout/sub1.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent" android:orientation="vertical">

    <TextView
            android:text="부분화면1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" android:id="@+id/textView2"
            android:textSize="30sp"
    />
    <CheckBox
            android:text="동의합니다."
            android:layout_width="match_parent"
            android:layout_height="wrap_content" android:id="@+id/checkBox"/>
</LinearLayout>

다음으로 MainActivity.java를 아래와 같이 작성한다.

 

◎MainActivity.java

package com.example.myapplication;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;

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 v) {
                LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                inflater.inflate(R.layout.sub1, container, true);
                CheckBox checkBox = container.findViewById(R.id.checkBox);

                checkBox.setText("로딩되었어요.");
            }
        });
    }
}

앞서 언급한 것과 같이 getSystemService메서드를 사용하여 LayoutInflater객체를 참조하여 가져왔다. 이후에 inflate() 메서드로 R.layout.sub1 파일을 container의 부분 레이아웃으로 설정했다.

 

inflate() 메서드는 첫번째 파라미터로 부분 XML 레이아웃 리소스를, 두번째 파라미터로 부모 컨테이너를 지정하고, 세번째 파라미터는 컨테이너 레이아웃에 부분 xml 레이아웃을 Attach할 것인지를 묻는다. (세번째 파라미터의 기본 값은 true이고, false일 시 에러가 나기 때문에 생략해도 무관하다.)

 

또한 LayoutInflater객체는 시스템 서비스로 제공되므로 위와 같이 getSystemService()를 호출하는 방법을 사용하거나, 아래와 같이 LayoutInflater 클래스의 from() 메서드를 호출하여 참조할 수도 있다.

 

◎MainActivity.java

package com.example.myapplication;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;

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 v) {
                /*LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);*/
                LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
                inflater.inflate(R.layout.sub1, container);
                CheckBox checkBox = container.findViewById(R.id.checkBox);

                checkBox.setText("로딩되었어요.");
            }
        });
    }
}

Comments