본문 바로가기

Android/View

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

안드로이드/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 예제 

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은 동일한 작업 입니다.

<자바코드>

// 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



스크린샷 :