2011-12-04 2 views
7

Android 용 사용자 정의 XML 데이터 유형을 만드는 방법이 있습니까?사용자 정의 XML 데이터 유형을 만드시겠습니까?

나는 내 엔티티의 모든 통계를 포함하는 클래스 Model을 가지고 있습니다. 나는 xml과 비슷한 Model 클래스를 부 풀릴 수 있기를 원한다. 이것이 가능한가?

예 :

<?xml version="1.0" encoding="utf-8"?> 
<models xmlns:android="http://schemas.android.com/apk/res/android"> 
    <model name="tall_model" 
     type="@string/infantry" 
     stat_attack="5" 
     >Tall Gunner</model> 

    <model name="short_model" 
     type="@string/infantry" 
     stat_attack="3" 
     ability="@resource/scout" 
     >Short Gunner</model> 

    <model name="big_tank" 
     type="@string/vehicle" 
     stat_attack="7" 
     armour="5" 
     >Big Tank</model> 
</models> 

내가하고 싶은 클래스가 팽창하기.

class Model [extends Object] { 
    public Model(Context context, AttributeSet attrs) { 
     // I think you understand what happens here. 
    } 
    // ... 
} 

답변

8

엄선 된 API를 사용하는 맞춤 코드를 사용하면 Android에서 레이아웃 XML 파일을 확장하는 방식을 모방 할 수 있으며 Android에서 컴파일 된 XML 파일 및 사용자 정의 XML 파일 내의 임의 리소스에 대한 참조와 같은 XML 최적화 및 이점을 계속 활용할 수 있습니다. 해당 클래스는 View을 팽창시킬 수 있기 때문에 기존 LayoutInflater에 직접 연결할 수 없습니다. 아래 코드가 작동하려면 XML 파일을 응용 프로그램의 'res/xml'에 넣으십시오.

먼저 (컴파일 된) XML 파일을 구문 분석하고 Model 생성자를 호출하는 코드는 다음과 같습니다. 등록 메커니즘을 추가하여 모든 태그에 대해 클래스를 쉽게 등록하거나 ClassLoader.loadClass()을 사용하여 클래스 이름을 기반으로 클래스를로드 할 수 있습니다. 이와

public class CustomInflator { 
    public static ArrayList<Model> inflate(Context context, int xmlFileResId) throws Exception { 
     ArrayList<Model> models = new ArrayList<Model>(); 

     XmlResourceParser parser = context.getResources().getXml(R.xml.models); 
     Model currentModel = null; 
     int token; 
     while ((token = parser.next()) != XmlPullParser.END_DOCUMENT) { 
      if (token == XmlPullParser.START_TAG) { 
       if ("model".equals(parser.getName())) { 
        // You can retrieve the class in other ways if you wish 
        Class<?> clazz = Model.class; 
        Class<?>[] params = new Class[] { Context.class, AttributeSet.class }; 
        Constructor<?> constructor = clazz.getConstructor(params); 
        currentModel = (Model)constructor.newInstance(context, parser); 
        models.add(currentModel); 
       } 
      } else if (token == XmlPullParser.TEXT) { 
       if (currentModel != null) { 
        currentModel.setText(parser.getText()); 
       } 
      } else if (token == XmlPullParser.END_TAG) { 
       // FIXME: Handle when "model" is a child of "model" 
       if ("model".equals(parser.getName())) { 
        currentModel = null; 
       } 
      } 
     } 

     return models; 
    } 
} 

장소에, 당신은 View 그것을하지 많은처럼 Model 클래스 내부 속성의 "분석"넣을 수 있습니다 :

public class Model { 
    private String mName; 
    private String mType; 
    private int mStatAttack; 
    private String mText; 

    public Model(Context context, AttributeSet attrs) { 
     for (int i = 0; i < attrs.getAttributeCount(); i++) { 
      String attr = attrs.getAttributeName(i); 
      if ("name".equals(attr)) { 
       mName = attrs.getAttributeValue(i); 
      } else if ("type".equals(attr)) { 
       // This will load the value of the string resource you 
       // referenced in your XML 
       int stringResource = attrs.getAttributeResourceValue(i, 0); 
       mType = context.getString(stringResource); 
      } else if ("stat_attack".equals(attr)) { 
       mStatAttack = attrs.getAttributeIntValue(i, -1); 
      } else { 
       // TODO: Parse more attributes 
      } 
     } 
    } 

    public void setText(String text) { 
     mText = text; 
    } 

    @Override 
    public String toString() { 
     return "model name=" + mName + " type=" + mType + " stat_attack=" + mStatAttack + " text=" + mText; 
    } 
} 

을 내가 문자열 표현을 통해 특성을 참조한 위. 추가로 이동하려는 경우 응용 프로그램 특정 속성 자원을 정의하여 대신 사용할 수 있지만 그 작업은 상당히 복잡합니다 (Declaring a custom android UI element using XML 참조). 어쨌든, 모든 리소스 설정이의 더미 활동 :이 출력을 얻을 것이다

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    try { 
     for (Model m : CustomInflator.inflate(this, R.xml.models)) { 
      Log.i("Example", "Parsed: " + m.toString()); 
     } 
    } catch (Exception e) { 
     Log.e("Example", "Got " + e); 
    } 
} 

:

I/Example (1567): Parsed: model name=tall_model type=Example3 stat_attack=5 text=Tall Gunner 
I/Example (1567): Parsed: model name=short_model type=Example3 stat_attack=3 text=Short Gunner 
I/Example (1567): Parsed: model name=big_tank type=Example2 stat_attack=7 text=Big Tank 

주 당신이 당신의 XML 파일에 @resource/scout을 가질 수 없습니다 resource이 아니므로 올바른 리소스 유형이지만 @string/foo이 정상적으로 작동합니다. 예를 들어 @drawable/foo을 사용하여 코드를 약간 수정하면됩니다.

+0

매우 상세한 답변을 주셔서 감사합니다. 너는 나의 영웅이야. – AedonEtLIRA

0

Android에서 XML 직렬화 메커니즘이 일관되지 않습니다. Gson 라이브러리 대신 Json을 대신 권하고 싶습니다.

1

예를 들어 TextView, EditText와 같은 기존보기 클래스를 확장하면 xml 레이아웃에서 호출 할 수 있습니다.

사용자 지정 구성 요소의 경우 Android Reference입니다.

너도 example이고 another one 인 xml attrubutes를 정의 할 수 있습니다.

나는 그것이 당신을 위해 도움이되기를 바랍니다!

+0

입력 해 주셔서 감사합니다.하지만보기 또는 다른 위젯을 확장하지 않습니다.내 문자열 및 정수 XML 파일 [R]에서 정의한 리소스를 가리키는 원시 xml 파일을 갖고 싶습니다. – AedonEtLIRA

관련 문제