본문 바로가기
안드로이드

XML 사용자 속성 정의 및 사용하기

by 호군 2011. 3. 17.
반응형
○ 순서는 아래와 같습니다.
  1. 먼저 attrs.xml에서 사용자 attribute를 정의한다.
  2. xml에서 사용자 widget의 속성에 사용자 attribute를 정의한다. 
    ※ 먼저 사용자 widget을 만들어야 합니다.(ex. 간단한 방법은 안드로이드 기본 widget을 상속 함)
  3. 소스코드(.java)에서 사용자 attribute 값을 가져온다.
  4. 가져온 값을 사용한다.

1. attrs.xml
[res/values/attrs.xml]

<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <declare-styleable name="CustomWidget">
        <attr name="firstAttribute" format="boolean"/>
        <attr name="secondAttribute" format="integer"/>
        <attr name="thirdAttribute" format="float"/>
        <attr name="fourthAttribute" format="dimension"/>
        <attr name="sixthAttribute" format="reference"/>
        <attr name="seventhAttribute" format="string"/>
        <attr name="eighthAttribute" format="color"/>
        <attr name="ninthAttribute" format="fraction"/>
        <attr name="tenthAttribute" format="enum"/>
        <attr name="eleventhAttribute" format="flag"/>
    </declare-styleable>
</resources>

2. main.xml 에서 사용자 widget에 attribute와 사용자 attribute를 추가 합니다.
[res/layout/main.xml]

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom=http://schemas.android.com/apk/res/com.dhna.attributetest
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <com.dhna.attributetest.CustomWidget
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        custom:firstAttribute="true"
        custom:secondAttribute="2"
        custom:thirdAttribute="3.5"
        custom:forthAttribute="10dp"
        custom:sixthAttribute="@drawable/test_drawable"
        custom:seventhAttribute="TestAttribute"
        custom:eighthAttribute="#FF666666"
</LinearLayout>
여기서 중요한것은 custom 이라는 xml의 namespace를 정의했다는 것이고, 그 namespace에 각 속성들을 썻다는 것입니다.
ninthAttribute, tenthAttribute, eleventhAttribute 속성은 사용해보지 않았습니다. 필요하신분은 찾아서 해보시길...

3. 소스코드(AttributeTest.java)에서 각 속성에 설정된 값을 가져온다.
가져오는 방법은 첫번째로 순회하는 방법과 두번째로 직접 attribute를 명시해서 가져오는 방법이 있습니다.

 [1] 첫번째 방법
[src/dhna/AttributeTest.java] 의 생성자

...
public AttributeTest(Context context, AttritubeSet attrs) {
    for(int i = 0 ; i < attrs.getAttributeCount() ; i++){
        String attributeName = attrs.getAttributeName(i);
        if(attributeName == "firstAttribute"){
            mBoolean = attrs.getAttributeBooleanValue(i, true); 
        }else if(attributeName == "secondAttribute"){
            mInteger = attrs.getAttributeIntValue(i, 0);
        }else if(attributeName == "thirdAttribute"){
            mFloat = attrs.getAttributeFloatValue(i, 0.5);
        }else if(attributeName == "forthAttribute"){
            //mDimension = attrs.getAttributeIntValue(i, 0xFFFFFFFF);
        }else if(attributeName == "sixthAttribute"){
            mReference= attrs.getAttributeResourceValue(i, R.drawable.icon);
        }else if(attributeName == "seventhAttribute"){
            mString= attrs.getAttributeValue(i);
        }    
    }
}
...

Dimension 부분은 저렇게 가져와야 할지 모르겠네요..ㅎㅎ;
안되시는건 직접 사용하셔서... 확인 부탁드려요 ㅠ

 [2] 두번째 방법
[src/dhna/AttributeTest.java] 의 생성자

...
public AttributeTest(Context context, AttritubeSet attrs) {
    TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomWidget);

    mBoolean = typedArray.getBoolean(R.styleable.CustomWidget_firstAttribute, true);
    mInteger = typedArray.getInt(R.styleable.CustomWidget_secondAttribute, 0);
    mFloat = typedArray.getFloat(R.styleable.CustomWidget_thirdAttribute, 0.5);
    mDimension = typedArray.getDimensionPixelSize(R.styleable.CustomWidget_forthAttribute, 0);
    mReference = typedArray.getResourceId(R.styleable.CustomWidget_thirdAttribute.sixthAttribute, R.drawable.icon);
    mString = typedArray.getString(R.styleable.CustomWidget_seventhAttribute);
    
    typedArray.recycle();
}
...

여기서 mReference는 리소스의 ID이기 때문에, 만약 이 리소스가 Drawable타입이라면, getResources().getDrawable(mReference) 로 Drawable을 얻어 올 수 있습니다.


4. 가져온 값(mBoolean, mInteger, mFloat, ...)을 필요한 곳에 사용하시면 됩니다.



 Tip
1. 첫번째 방법은 XML에 설정한 모든 속성(Attribute)을 가져 올 수 있습니다.
   만약 android의 속성값을 가져오기 위해서는 아래와 같이 하시면 됩니다.
   int orientation = attrs.getAttributeIntValue("http://schemas.android.com/apk/res/android", "orientation", 0);

2. 두번째 방법은 사용자가 정의한 속성(Attribute)를 가져오는 방법입니다.
    실험해보진 않았지만, 위의 방법으로 해당 속성을 갖은 namespace 부분만 
    설정한다면 역시 가져 올 수 있을 것이라 생각합니다. 사용자 속성은 두번째
    방법이 편할 것이라고 생각되네요.


반응형