Android में शैलीगत विशेषताओं की घोषणा


81

उस declare-styleableटैग के बारे में अनमोल दस्तावेज हैं जिनके द्वारा हम घटकों के लिए कस्टम शैलियों की घोषणा कर सकते हैं। मुझे टैग की विशेषता के लिए मान्य मानों की यह सूची मिली । जबकि यह अच्छा है जहाँ तक यह जाता है, यह नहीं समझाता है कि उन मूल्यों में से कुछ का उपयोग कैसे करें। ब्राउज़िंग attr.xml (मानक विशेषताओं के लिए Android स्रोत), मैंने पाया कि आप इस तरह की चीजें कर सकते हैं:formatattr

<!-- The most prominent text color.  -->
<attr name="textColorPrimary" format="reference|color" />

formatविशेषता जाहिर मूल्यों के संयोजन के लिए सेट किया जा सकता। संभवतः यह formatगुण पार्सर को वास्तविक शैली मान की व्याख्या करने में मदद करता है। तब मैंने इसे attr.xml में खोजा:

<!-- Default text typeface. -->
<attr name="typeface">
    <enum name="normal" value="0" />
    <enum name="sans" value="1" />
    <enum name="serif" value="2" />
    <enum name="monospace" value="3" />
</attr>

<!-- Default text typeface style. -->
<attr name="textStyle">
    <flag name="normal" value="0" />
    <flag name="bold" value="1" />
    <flag name="italic" value="2" />
</attr>

ये दोनों संकेतित शैली के लिए अनुमत मूल्यों के एक सेट की घोषणा करते प्रतीत होते हैं।

इसलिए मेरे दो सवाल हैं:

  1. एक शैली विशेषता के बीच क्या अंतर है जो enumमूल्यों के एक सेट पर ले जा सकता है और एक जो flagमूल्यों के एक सेट पर ले जा सकता है ?
  2. किसी को भी कैसे declare-styleableकाम करता है (रिवर्स इंजीनियरिंग Android स्रोत कोड के अलावा) के लिए किसी भी बेहतर प्रलेखन का पता है ?

जवाबों:


74

यहां यह सवाल है: कुछ के साथ कस्टम अटैक्स को परिभाषित करना जानकारी के , लेकिन बहुत नहीं।

और यह पोस्ट । यह झंडे और enums के बारे में अच्छी जानकारी है:

कस्टम XML विशेषता झंडे

झंडे विशेष प्रकार के गुण होते हैं, जिसमें उन्हें केवल मानों के बहुत छोटे उपसमूह की अनुमति दी जाती है, अर्थात् जिन्हें विशेषता टैग के नीचे परिभाषित किया जाता है। झंडे एक "नाम" विशेषता और एक "मूल्य" विशेषता द्वारा निर्दिष्ट किए गए हैं। नाम उस विशेषता प्रकार के भीतर अद्वितीय होने के लिए आवश्यक हैं, लेकिन मानों की आवश्यकता नहीं है। यही कारण है कि एंड्रॉइड प्लेटफॉर्म के विकास के दौरान हमारे पास "fill_parent" और "match_parent" दोनों समान व्यवहार के लिए मैपिंग थे। उनके मूल्य समान थे।

नाम विशेषता लेआउट XML में मूल्य स्थान में उपयोग किए गए नाम के लिए मैप करता है और इसके लिए नामस्थान उपसर्ग की आवश्यकता नहीं होती है। इसलिए, ऊपर "tilingMode" के लिए मैंने विशेषता मान के रूप में "केंद्र" चुना। मैं बस के रूप में आसानी से चुना जा सकता है "बढ़ाया" या "दोहरा" लेकिन कुछ और नहीं। वास्तविक मूल्यों में प्रतिस्थापित करने की भी अनुमति नहीं दी गई है।

मान विशेषता पूर्णांक होनी चाहिए। हेक्साडेसिमल या मानक अंक प्रतिनिधित्व का विकल्प आपके ऊपर है। एंड्रॉइड कोड के भीतर कुछ स्थान हैं जहां दोनों का उपयोग किया जाता है और एंड्रॉइड कंपाइलर या तो स्वीकार करने में प्रसन्न होता है।

कस्टम XML विशेषता Enums

Enums का उपयोग लगभग एक समान तरीके से झंडे के रूप में किया जाता है, एक प्रावधान के साथ इनका उपयोग किया जा सकता है। हुड के तहत Enums और Integers एक ही डेटा प्रकार, अर्थात् एक पूर्णांक में मैप किए जाते हैं। जब इंटेगर के साथ विशेषता परिभाषा में दिखाई देते हैं, तो एनम "जादू की संख्या" को रोकने के लिए सेवा करते हैं जो हमेशा खराब होते हैं। यही कारण है कि आपके पास आयाम, पूर्णांक, या नामित स्ट्रिंग "fill_parent" के साथ एक "एंड्रॉइड: लेआउट_ एक्सपोजर" हो सकता है।

इसे संदर्भ में रखने के लिए, मान लें कि मैं एक कस्टम विशेषता बनाता हूं, जिसे "layout_scroll_height" कहा जाता है, जो एक पूर्णांक या एक स्ट्रिंग "स्क्रॉल_टो_टॉप" को स्वीकार करता है। ऐसा करने के लिए, मैं एक "पूर्णांक" प्रारूप विशेषता जोड़ूंगा और उस का अनुसरण करूंगा:

<attr name="layout_scroll_height" format="integer">  
    <enum name="scroll_to_top" value="-1"/> 
</attr>

इस तरह से एनम का उपयोग करते समय एक शर्त यह है कि आपके कस्टम व्यू का उपयोग करने वाला एक डेवलपर उद्देश्य मान को "-1" लेआउट मानकों में रख सकता है। यह "स्क्रोल_टो_टॉप" के विशेष केस लॉजिक को ट्रिगर करेगा। इस तरह के अनपेक्षित (या अपेक्षित) व्यवहार से आपकी लाइब्रेरी को "विरासत कोड" के ढेर पर फिर से जमा किया जा सकता है यदि एनम के मूल्यों को खराब तरीके से चुना गया था।


जैसा कि मैं इसे देखता हूं, आप वास्तविक विशेषताओं को एक विशेषता में वास्तविकता में जोड़ सकते हैं जो आप इसे प्राप्त कर सकते हैं द्वारा सीमित है। चेक AttributeSetवर्ग संदर्भ यहाँअधिक संकेत के लिए ।

आप प्राप्त कर सकते हैं:

  • बूलियन (getAttributeBooleanValue ),
  • तैरता है (getAttributeFloatValue ),
  • ints (getAttributeIntValue ),
  • ints (as) getAttributeUnsignedIntValue ),
  • और तार ( getAttributeValue)

उन लिंक के लिए धन्यवाद। स्टेटिकली टाइप्ड ब्लॉग विशेष रूप से अच्छा है। यह "वास्तविक प्रलेखन" के काफी करीब है कि मैं इसे हल कर रहा हूं।
टेड होप

@ सच में, उस पोस्ट में बहुत अच्छी जानकारी है। किसी भी तरह, जब तक आप पुन: प्रयोज्य विचारों का पुस्तकालय नहीं लिख रहे हैं, या ढांचे का विस्तार नहीं कर रहे हैं, मैं इन बातों की चिंता नहीं करूंगा। बूल, फ़्लोट, इन्टस और स्ट्रिंग्स आपको नियमित कस्टम दृश्यों के लिए बहुत दूर ले जा सकते हैं। यह निश्चित रूप से, अगर सवाल सिर्फ एक बहुत ही स्वस्थ जिज्ञासा को संतुष्ट करने का नहीं था :)
अलिदम

@Aleadam - प्रश्न एक वास्तविक आवेदन से प्रेरित था। मैं कस्टम विशेषताओं का उपयोग कर रहा हूं और एक नया जोड़ने की आवश्यकता है। ऐसा लगता है कि नई विशेषता के लिए सही प्रारूप एक enum है, लेकिन लिंक आपके द्वारा दी गई पढ़ने जब तक, मैं का उपयोग कर के बीच अंतर के बारे में कोई जानकारी नहीं मिल सकता है enumऔर flag
टेड होप

@ मुझे खुशी है कि यह उपयोगी था। उस ब्लॉग में कुछ अन्य पोस्ट हैं जो दिलचस्प लगते हैं, हालाँकि मैं अभी इसके माध्यम से स्किम करता हूँ, मेरे पास अभी उन्हें पढ़ने का समय नहीं था।
अलिदम

3
मेरे ब्लॉग को लिंक करने वाले किसी भी व्यक्ति के लिए +1। मैंने वास्तव में उन टैग्स के माध्यम से पार्स करने की कोशिश की, जिनमें से प्रत्येक का उपयोग किया गया था। यह पूर्ण नहीं हो सकता है और शायद समय के अनुसार अद्यतन किया जाना चाहिए, लेकिन अगर किसी को इसमें कुछ भी जोड़ना है, तो मैं सभी कान हूं।
गेहूं

70

@ अलीदाम का जवाब बहुत मददगार है, लेकिन इहो इसके बीच एक बड़े अंतर को छोड़ देता है enumऔरflag । पूर्व हमें एक लेने के लिए इरादा है, और केवल एक मूल्य जब हम कुछ दृश्य के लिए इसी विशेषता को असाइन करते हैं। बाद के मूल्यों को संयुक्त किया जा सकता है, हालांकि, बिटवाइज़ या ऑपरेटर का उपयोग करके।

एक उदाहरण, में res/values/attr.xml

<!-- declare myenum attribute -->
<attr name="myenum">
    <enum name="zero" value="0" />
    <enum name="one" value="1" />
    <enum name="two" value="2" />
    <enum name="three" value="3" />
</attr>

<!-- declare myflags attribute -->
<attr name="myflags">
    <flag name="one" value="1" />
    <flag name="two" value="2" />
    <flag name="four" value="4" />
    <flag name="eight" value="8" />
</attr>

<!-- declare our custom widget to be styleable by these attributes -->
<declare-styleable name="com.example.MyWidget">
    <attr name="myenum" />
    <attr name="myflags" />
</declare-styleable>

में res/layout/mylayout.xmlअब हम क्या कर सकते हैं

<com.example.MyWidget
    myenum="two"
    myflags="one|two"
    ... />

तो एक एनम अपने संभावित मूल्यों में से एक का चयन करता है, जबकि झंडे संयुक्त हो सकते हैं। संख्यात्मक मान इस अंतर को दर्शाते हैं, आम तौर पर आप चाहते हैं कि अनुक्रम 0,1,2,3,...enums के लिए जाना होगा (सरणी सूचकांकों के रूप में इस्तेमाल किया जा सकता है, कहते हैं) और जाने के लिए झंडे 1,2,4,8,...इसलिए उन्हें स्वतंत्र रूप से जोड़ा या हटाया जा सकता है, बिटवाइज़ का उपयोग कर या |झंडे को संयोजित करने के लिए।

हम स्पष्ट रूप से "मेटा फ्लैग" को उन मूल्यों के साथ परिभाषित कर सकते हैं जो 2 की शक्ति नहीं हैं, और इस तरह सामान्य संयोजनों के लिए एक प्रकार का आशुलिपि का परिचय देते हैं। उदाहरण के लिए, यदि हमने अपनी myflagsघोषणा में इसे शामिल किया था

<flag name="three" value="3" />

तब हम myflags="three"लगातार के myflags="one|two"समान परिणामों के लिए लिख सकते थे 3 == 1|2

व्यक्तिगत रूप से, मुझे हमेशा शामिल करना पसंद है

<flag name="none" value="0" /> <!-- or "normal, "regular", and so on -->
<flag name="all" value="15" /> <!-- 15 == 1|2|4|8 -->

जो मुझे एक ही बार में सभी झंडे सेट करने या सेट करने की अनुमति देगा।

अधिक सूक्ष्म रूप से, यह मामला हो सकता है कि एक ध्वज दूसरे द्वारा निहित है। इसलिए, हमारे उदाहरण में, मान लें कि eightसेट किए जा रहे fourध्वज को ध्वज को सेट करने के लिए बाध्य करना चाहिए (यदि यह पहले से नहीं था)। हम फिर eightसे पूर्व -सम्‍मिलित कर सकते हैं, जैसा कि यह था, fourझंडा,

<flag name="eight" value="12" /> <!-- 12 == 8|4 -->

अंत में, यदि आप किसी लाइब्रेरी प्रोजेक्ट में विशेषताओं की घोषणा कर रहे हैं, लेकिन उन्हें किसी अन्य प्रोजेक्ट के लेआउट में लागू करना चाहते हैं (लीब पर निर्भर), तो आपको एक नामस्थान उपसर्ग का उपयोग करने की आवश्यकता होगी जिसे आपको XML रूट तत्व में बांधना होगा। जैसे,

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:auto="http://schemas.android.com/apk/res-auto"
    ... >

    <com.example.MyWidget
        auto:myenum="two"
        auto:myflags="one|two"
        ... />

</RelativeLayout>

अच्छे अंक। मुझे लगता है कि प्रोग्रामिंग लैंग्वेज से एनम से परिचित किसी व्यक्ति के लिए, एक झंडे और एक एनम के बीच का अंतर दूसरा स्वभाव होगा। (मुझे यह भी महसूस नहीं हुआ कि आप जो बिंदु बना रहे थे, वह अलएदम के उत्तर से गायब था।) यह निश्चित रूप से उपयोगी अतिरिक्त जानकारी है। +1
टेड हॉप

यह उत्तर स्पष्ट रूप से इंगित करता है कि कस्टम विशेषताओं को परिभाषित करते समय झंडे से अलग कैसे करें। यह स्पष्ट रूप से मुझे झंडे का उपयोग करने में मदद करता है :) +1
ptitvinou
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.