2013.11.09 22:56


안드로이드/Android LayoutInflater 사용 방법




1) LayoutInflater란?

XML에 정의된 Resource(자원) 들을 View의 형태로 반환해 줍니다. 보통 자바 코드에서 View, ViewGroup 을 사용하거나, Adpter의 getview() 또는 Dialog, Popup 구현시 배경화면이 될 Layout을 만들어 놓고 View의 형태로 반환 받아 Acitivity에서 실행 하게 됩니다.


우리가 보통 Activity를 만들면 onCreate() 메서드에 기본으로 추가되는 setContentView(R.layout.activity_main) 메서드와 같은 원리라고 생각하시면 됩니다. 이 메서드 또한 activity_main.xml 파일을 View로 만들어서 Activity 위에 보여주고 있습니다. 사용자의 화면에 보여지는 것들은 Activity 위에 있는 View라는 점을 잊지 말아 주세요~! 



2) LayoutInflater 예제 

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
package arabiannight.tistory.com.layoutinflater;
 
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView;
 
public class MainActivity extends Activity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
         
        // Inflater View 만들기
        View view = (View) getLayoutInflater().
                inflate(R.layout.activity_main, null);
         
        // Inflate된 View에서 Resource(ViewGroup) 얻어 오기~!
        RelativeLayout bg = (RelativeLayout) view.findViewById(R.id.rl_background);
        bg.setBackgroundColor(Color.GREEN);
         
        // Inflate된 View에서 Child인 TextView를 얻어 오기
        TextView tv = (TextView) view.findViewById(R.id.tv_content);
        tv.setGravity(Gravity.CENTER);
         
        // Child View인 TextView 속성 재정의 하기 (부모의 속성을 얻어옴)
        RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)
                tv.getLayoutParams();
         
        params.width = LayoutParams.MATCH_PARENT;
        params.height = LayoutParams.WRAP_CONTENT;
         
        tv.setLayoutParams(params);
         
         
        /**
         * <오류코드>
         * RelativeLayout.LayoutParams bg_params = (RelativeLayout.LayoutParams)
         *      bg.getLayoutParams();
         *
         *  bg.setLayoutParams(bg_params);
         */
         
        // bg는 위의 부모가 없기 때문에 위의 속성을 사용하면 에러 발생 후 죽게 됩니다.
        // 그래도 사용해야 되는 경우가 생긴다면
        // ViewGroup.LayoutParams 을 사용해서 넣어 주시거나(부모가 없어도 LayoutParams 사용가능)
        // XML에 빈 부모를 하나 더 생성 하셔서 bg를 차일드로 넣고 작업 하시기 바랍니다.^^
        // 빈 부모의 속성(LayoutParams)를 지정해 주셔야 합니다.
         
        setContentView(view);
         
    }
 
}



아래의 자바코드와 XML은 동일한 작업 입니다.

<자바코드>

1
2
3
4
5
6
7
8
// Child View인 TextView 속성 재정의 하기 (부모의 속성을 얻어옴)
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)
        tv.getLayoutParams();
         
params.width = LayoutParams.MATCH_PARENT;
params.height = LayoutParams.WRAP_CONTENT;
         
tv.setLayoutParams(params);


<XML 모습>



3) 주의사항 

<필독!!>

1) 위의 코드에서 bg(최상위 view) 는 위의 부모가 없기 때문에 위의 속성(getLayoutParams)을 사용하면 에러 발생 후 죽게 됩니다. 그래도 사용해야 되는 경우가 생긴다면 ViewGroup.LayoutParams 을 사용해서 넣어 주시거나 (부모가 없어도 LayoutParams 사용가능), XML에 빈 부모를 하나 더 생성 하셔서 bg를 차일드로 넣고 작업 하시기 바랍니다.^^ 차일드에 넣어 사용시 빈 부모의 속성(LayoutParams)를 지정해 주셔야 합니다.


2) LayoutInflater의 inflate() 메서드로 Layout을 inflate 한 경우에는 폴더별(Land, Port) Layout을 저절로 참조 하게 됩니다.


3) Resource ID(XML Layout의 Child View)는 inflate() 시 Casting 에러로 APP이 종료되게 됩니다. Resource ID 별로 inflate 시킬수가 없습니다. 꼭 Layout을 inflate 시켜야 View를 얻을 수 있습니다.


4) infalte 된 View의 Child 라면 findViewById는 절대 inflate된 View.findViewById 로 찾아야 합니다. 아니면 View를 참조 할 수 없습니다.


5) LayoutInflater된 View(xml)의 LayoutParems 속성은 (Width) wrap_content, (Height) wrap_content으로 변경 됩니다. 아무리 xml에 Layout_width, Layout_height 속성을 match_parent를 주어도 코드에서 infalte를 한다면 시스템은 infalte 된 View(xml)의 Layout_width,  Layout_height 속성을 wrap_content, wrap_content로 강제로 바꿔 버립니다. 왜냐하면 inflate된 View(xml)는 parent가 없어 지기 때문에 강제로 속성을 변경해 버리는 것이지요. 이점 꼭 명심하세요. ~!


6) inflate된 View에 다시 한번 LayoutInflater를 사용한다면 기존의 findviewID와 Event들이 모두 사라 집니다. View의 참조변수에 다른 객체를 넣는다고 생각 하시면 됩니다. 그렇다면 모두 초기화가 되겠죠? 이점 유의해 주세요^^




파일첨부 : 

TestLayoutinflater.zip




스크린샷 : 






신고


Posted by injunech