본문 바로가기

안드로이드

[Android] <include layout /> 인클루드 레이아웃












재사용 가능한 레이아웃을 만들고 사용하는 방법!
간단하지만 있는지를 모르면 아예 쓰지를 못하죠. 많이 해보는 것은 그래서 중요합니다.
어쨋든, 알아보도록 할게요.

Layout Tricks 레퍼런스 보기




우선 간단하게 순서를 말해볼게요.
1. 재사용할 layout xml (레이아웃 xml) 을 만든다. 위치 : res/layout
2. 액티비티와 매칭되는 레이아웃 xml에 include 태그를 추가한다. 
   이때 속성은 android:layout_xxx... 면 충분하다.

3. 액티비티 코드에서 include 한 레이아웃을 받아와 하고 싶은 처리를 한다.





 1. 재사용할 Layout XML 만들기

기본적인 LinearLayout 을 사용한 레이아웃이니 다른 설명은 생략하겠습니다.

res/layout/layout_textview.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">
    <TextView
        android:id="@+id/layout_textview_01"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:text="하이 헬로 첫번째 텍스트뷰"
        android:textSize="20sp"
        android:textColor="#FFFFFF" />
    <TextView
        android:id="@+id/layout_textview_02"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:text="하이 헬로 두번째 텍스트뷰"
        android:textSize="18sp"
        android:textColor="#808080" />
</LinearLayout>


res/layout/layout_button.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">
    <Button
        android:id="@+id/layout_button_01"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="하이 헬로 01" />
    <Button
        android:id="@+id/layout_button_02"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="하이 헬로 02" />
</LinearLayout>






 2. 액티비티의 XML에 include 로 재사용할 레이아웃 추가하기

기본 프로젝트에서 생성되는 xml로 처음에 액티비티를 만들면서 프로젝트를 생성한다면,
만들어진 기본 액티비티에 setContent 되어있는 레이아웃 xml 이다.


res/layout/main.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <include
        layout="@layout/layout_textview"
        android:id="@+id/main_layout_textview"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
    <include
        layout="@layout/layout_button"
        android:id="@+id/main_layout_button"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
</LinearLayout>


main.xml 이라는 레이아웃 xml의 코드를 잘 보면,
orientation이 vertical(자식뷰들을 세로로 배치하겠습니다.)로 되어있는 LinearLayout 안에 
include 가 2번 나오는 것을 볼 수 있습니다.

첫번째 include는 위의 1번에서 만든 layout_textview를 포함하는 녀석이고
두번째 include는 위의 1번에서 만든 layout_button을 포함하는 녀석입니다.

이렇게 하는 것 만으로 화면은 1번에서 만든 두 레이아웃을 포함하고 있게 됩니다.





 3. include한 레이아웃 받아서 처리하기

위의 처리들이 단순히 화면에 보이는 부분만을 위한 것이었다면,
여기서는 실제로 여러가지 세팅을 하고 이벤트를 처리하는 것을 할것입니다.

우선 첫번째로 텍스트뷰의 텍스트를 바꿀 것이고, (layout_textview 안의 두 텍스트뷰의 텍스트 바꾸기)
두번째로 버튼 클릭 이벤트를 처리할 것입니다.(layout_button 안의 두 버튼에 대한 클릭 이벤트를 처리)

우선 액티비티 전체 코드 입니다.

me.croute.example.layout/ExampleIncludeLayoutActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package me.croute.example.layout;
 
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
 
 
/**
 * include layout 예제
 * include layout에 대해서 간단한  코드를 통해 알아본다.
 *
 * @author croute
 * @since 2011.06.13
 */
public class ExampleIncludeLayoutActivity extends Activity implements OnClickListener
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
         
        // layout_textview를 받아온다. layout_textview를 받아온 View textView 객체는 하위 자식들을 그대로 포함하고 있다.
        // 이렇게 받아온 View textView는 layout_textview의 root뷰이다.
        View textView = (View)findViewById(R.id.main_layout_textview);
         
        // 받아온 textview를 통해 해당 View가 가진 하위 자식들을 받아온다.(reference한다.)
        TextView tv01 = (TextView)textView.findViewById(R.id.layout_textview_01);
        TextView tv02 = (TextView)textView.findViewById(R.id.layout_textview_02);
         
        // layout_button을 받아온다. layout_button을 받아온 View button 객체는 하위 자식들을 그대로 포함하고 있다.
        // 이렇게 받아온 View button은 layout_button의 root뷰이다.
        View button = (View)findViewById(R.id.main_layout_button);
         
        // button을 통해 해당 View가 가진 하위 자식들을 받아온다.(reference한다.)
        Button b01 = (Button)button.findViewById(R.id.layout_button_01);
        Button b02 = (Button)button.findViewById(R.id.layout_button_02);
         
        // 기존에 씌여져 있던 텍스트를 변경한다.
        tv01.setText("바뀐 하이 헬로 01");
        tv02.setText("바뀐 하이 헬로 02");
         
        // 버튼에 클릭 리스너를 등록한다.
        // implements OnClickListener 를 하고, onClick() 메소드를 구현하였기 때문에, this를 파라미터로 넣는다.
        b01.setOnClickListener(this);
        b02.setOnClickListener(this);
         
    }
 
    @Override
    public void onClick(View v)
    {
        // 각 버튼이 클릭 되었을 때의 이벤트를 처리한다.
        switch(v.getId())
        {
        // 위젯(뷰)아이디가 layout_button_01 인 버튼이 클릭되었을 경우의 이벤트
        case R.id.layout_button_01:
            Toast.makeText(this, "버튼 1 클릭", Toast.LENGTH_SHORT).show();
            break;
             
        // 위젯(뷰)아이디가 layout_button_02 인 버튼이 클릭되었을 경우의 이벤트
        case R.id.layout_button_02:
            Toast.makeText(this, "버튼 2 클릭", Toast.LENGTH_SHORT).show();
            break;
        }
    }
}




// layout_textview를 받아온다. layout_textview를 받아온 View textView 객체는 하위 자식들을 그대로 포함하고 있다.
// 이렇게 받아온 View textView는 layout_textview의 root뷰이다.
View textView = (View)findViewById(R.id.main_layout_textview);
         
// 받아온 textview를 통해 해당 View가 가진 하위 자식들을 받아온다.(reference한다.)
TextView tv01 = (TextView)textView.findViewById(R.id.layout_textview_01);
TextView tv02 = (TextView)textView.findViewById(R.id.layout_textview_02);

주석에 설명해 놓았듯이,
findViewById 로 받아오게 되면, textView 라는 View 인스턴스는 layout_textview 의 root 뷰를 가지게 되죠.

그렇기 때문에,!!
그 아래서 받아온 layout_textview의 root 뷰, 즉 textview 라는 View 인스턴스를 통해 하위 자식들까지 받아올 수 있는 것입니다. 

컨테이너 개념만 알면 아주 쉽게 이해할 수 있는 부분이죠. 또는 뷰와 뷰그룹, 위젯들의 관계를 알고 있어도 쉽습니다.
(뷰와 뷰 그룹, 위젯에 대한 설명 : 
[Android] Activity, Window, android.widget, View, ViewGroup http://croute.me/425 )

그리고 그 세부적인 처리는 일반적으로 하듯이 처리하면 됩니다.
텍스트뷰에 대해서는 TextView.setText() 메소드를 통해,
버튼에 대해서는 Button.setOnClickListener() 메소드를 통해 리스너를 등록하고 onClick() 메소드에서 처리하는 것이죠.

이렇게 해두면 굳이 inflater를 통해 객체화 시켜서 여러가지에 대해서 처리 할 필요 없이,
레퍼런스에 레퍼런스를 하는 것만으로 많은 처리를 할 수 있게 됩니다.

이렇게 처리했을때의 가장 큰 장점은 
하나의 레이아웃을 만들어두고 여러 레이아웃에서 손쉽게 재사용 할 수 있다는 것이겠죠?



예제 스크린샷




예제 프로젝트 파일 첨부