본문 바로가기

프로그래밍/Android

Custom layout, layoutinflater

 

커스텀 레이아웃과 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