2011-12-04 13 views
7

क्या Android के लिए कस्टम XML डेटा प्रकार बनाने का कोई तरीका है?एक कस्टम एक्सएमएल डेटा प्रकार बनाएँ?

मेरे पास कक्षा Model है जिसमें मेरी संस्थाओं के सभी आंकड़े शामिल हैं। मैं Model वर्ग को एक्सएमएल से समान रूप से बढ़ाने में सक्षम होना चाहता हूं - ठीक है, दृश्य के रूप में exaclty। क्या यह संभव है?

उदाहरण:

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

ध्यान से चयनित एपीआई का उपयोग करके कुछ कस्टम कोड के साथ, आप एंड्रॉइड लेआउट एक्सएमएल फाइलों को बढ़ाने के तरीके की नकल कर सकते हैं और अभी भी एक्सएमएल ऑप्टिमाइज़ेशन और गुड्स से लाभ प्राप्त कर सकते हैं कि एंड्रॉइड को आपकी कस्टम एक्सएमएल फाइलों के भीतर एक्सएमएल फाइलों और मनमानी संसाधनों के संदर्भों की तरह है। आप सीधे मौजूदा LayoutInflater में शामिल नहीं हो सकते हैं क्योंकि वह वर्ग केवल View एस को बढ़ाने के साथ सौदा कर सकती है। नीचे दिए गए कोड को काम करने के लिए, अपने एक्सएमएल फ़ाइल को अपने एप्लिकेशन में 'res/xml' में रखें।

पहला, यहां कोड है जो संकलित (संकलित) एक्सएमएल फ़ाइल को पार्स करता है और Model कन्स्ट्रक्टर को आमंत्रित करता है। आप कुछ पंजीकरण तंत्र जोड़ना चाह सकते हैं ताकि आप आसानी से किसी भी टैग के लिए कक्षा पंजीकृत कर सकें, या आप ClassLoader.loadClass() का उपयोग करना चाहें ताकि आप उनके नाम के आधार पर कक्षाएं लोड कर सकें। ऊपर मैं स्ट्रिंग प्रतिनिधित्व के माध्यम से गुण संदर्भित किया है

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; 
    } 
} 

:

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; 
    } 
} 
इस के साथ

जगह में, आप Model वर्ग के भीतर विशेषताओं के "पार्स करने", View यह होता है बहुत पसंद डाल सकते हैं। यदि आप आगे जाना चाहते हैं, तो आप एप्लिकेशन विशिष्ट विशेषता संसाधनों को परिभाषित कर सकते हैं और इसके बजाय उन लोगों का उपयोग कर सकते हैं, लेकिन इससे चीजों को थोड़ा जटिल बना दिया जाएगा (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

एक्सएमएल क्रमबद्धता तंत्र एंड्रॉइड पर संगत नहीं है। मैं संभवतः जीसन पुस्तकालय के साथ, जेसन की सिफारिश करता हूं।

1

यदि आप टेक्स्ट व्यू, एडिटटेक्स्ट उदाहरण के लिए मौजूदा व्यू क्लास का विस्तार करते हैं, तो आप इसे एक्सएमएल लेआउट के अंदर कॉल कर सकते हैं।

यह कस्टम घटक के लिए Android Reference है।

और आप कस्टम एक्सएमएल एट्रूट्यूट भी परिभाषित कर सकते हैं, यह example और another one है।

मुझे उम्मीद है कि यह आपके लिए मदद करता है!

+0

इनपुट के लिए धन्यवाद, लेकिन मैं व्यू या कोई अन्य विजेट विस्तारित नहीं कर रहा हूं।मैं एक कच्ची एक्सएमएल फ़ाइल चाहता हूं जो संसाधनों को इंगित करता है जिन्हें मैंने अपनी स्ट्रिंग और पूर्णांक एक्सएमएल फाइलों [आर] में परिभाषित किया है। – AedonEtLIRA

संबंधित मुद्दे