커스텀 레이아웃과 LayoutInflater
레이아웃은 View을 상속받아 만드는 커스텀뷰와 큰 차이는 없으나, 자식뷰들이 존재하므로 그에대한
고려만 추가해 주면 된다.
LayoutInflater를 통해 액티비티용으로 구성된 레이아웃을 붙여 다른 뷰그룹에 포함될 수 있는
커스텀 레이아웃을 만들수 있다.
커스텀 레이아웃은 ViewGroup을 상속받으며,
onMeasure() , onLayout() 메쏘드를 오버라이딩해 구현해 주어야 한다.
뷰와 차이는 없으나 자식뷰에 대한 처리가 추가된다.
각 자식뷰를 돌면서 사이즈 정보를 넘겨야 한다.
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int count = getChildCount();
int maxHeight = 0;
int maxWidth = 0;
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
measureChild(child, widthMeasureSpec, heightMeasureSpec);
}
}
maxWidth += getPaddingLeft() + getPaddingRight();
maxHeight += getPaddingTop() + getPaddingBottom();
Drawable drawable = getBackground();
if (drawable != null) {
maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
}
setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
resolveSize(maxHeight, heightMeasureSpec));
}
다음은 onLayout인데, 사이즈가 변경이 되면 호출된다.
역시 자식뷰들에 대해 padding을 적용하고, raw 픽셀크기를 적용시켜 준다.
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int count = super.getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
final int childLeft = getPaddingLeft();
final int childTop = getPaddingTop();
child.layout(childLeft, childTop,
childLeft + child.getMeasuredWidth(),
childTop + child.getMeasuredHeight());
}
}
}
이하의 내용은 Custom View와 큰 차이가 없다.
xml 레이아웃에 포함시키고자 한다면 기존 포스트 http://blog.daum.net/hopefullife/105 참조.
대강 정리하면..
xml에 레이아웃을 사용하기 위해서는
public MyLayout(Context context, AttributeSet attrs ) 를 상속받아야 하고,
속성들을 지정하기 위해 /res/values/ 에 스타일을 선언해 주어야 한다.
속성지정
/res/values/my_attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name = "MyLayoutStyle">
<attr name="attr_1" format="integer"/>
<attr name="attr_2" format="boolean"/>
</declare-styleable>
</resources>
레이아웃
<com.test.MyLayout xmlns:myns = http://schemas.android.com/apk/res/com.test
.
.
myns:attr_1="1"
myns:attr_2="true"
/>
속성읽기
public void MyLayout(Context context, AttributeSet attrs ) {
TypedArray ta = context.obtainStyledAttributes( attrs, R.styleable.MyLayoutStyle );
int v1 = ta.getInteger( R.styleable.MyLayoutStyle_attr_1, 0 );
boolean b = ta.getBoolean( R.styleable.MyLayoutStyle_attr_2, false);
}
이런 형태가 되어 속성에 따른 처리를 넣으면 된다.
코드상에서 레이아웃을 생성하는 경우와 다른 레이아웃을 가져와 적용을 위해서는 inflater가 필요한데,
이 역시 간단히 처리된다.
/layout/my_activity_layout.xml
public MyLayout( Context context ) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService( Context.LAYOUT)INFLATER_SERVICE);
// 레이아웃 얻기
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.my_activity_layout, null );
// 필요한 뷰들을 가져온다.
TextView text = (TextView) root.findViewById( R.id.어쩌구 );
ImageView img = (ImageView) root.findViewById( R.id.저쩌구 );
.
.
// 현재 레이아웃에 추가한다.
this.addView( root );
}
이제 일반적인 레이아웃처럼 addView 해서 사용하면 된다.
'프로그래밍 > Android' 카테고리의 다른 글
최상위 뷰 만들기 (0) | 2011.10.27 |
---|---|
OpenGL 프레임버퍼 사용 (0) | 2011.10.27 |
ADB tcp/usb 연결설정 (0) | 2011.10.26 |
sdk3.0 fragment를 하위버전에서 사용하기 (0) | 2011.10.19 |
SurfaceView/GLSurfaceView (0) | 2011.10.11 |
MediaStore 썸네일 데이터 관련 정리 (0) | 2011.09.26 |
뷰의 크기 변경,이동 (0) | 2011.09.23 |
리스트뷰 메쏘드 몇개 (0) | 2011.09.22 |
SQLite Database (0) | 2011.09.20 |
Edittext 관련 사항들 (0) | 2011.09.18 |