2013-02-12 20 views
5

समझ में नहीं आ रहा है मैं एंड्रॉइड डेवलपमेंट में नया हूं और मैं यह समझने के लिए एक छोटा ऐप लिख रहा हूं कि यह कैसे काम करता है। मुझे सब काम मिल गया है, लेकिन फिलहाल मुझे कस्टम ड्रॉइंग स्टेटस के बारे में कोई बात नहीं मिल सकती है ... मुझे कुछ नमूना कोड के साथ समझाएं।एंड्रॉइड कस्टम ड्रायबल स्टेटस

<?xml version="1.0" encoding="utf-8"?> 
<com.example.calendar.DayView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="90dp" 
    android:background="@drawable/dayview_state" > 
    <TextView android:id="@+id/day_number" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentTop="true" 
     android:layout_alignParentRight="true" 
     android:paddingRight="3dp" /> 
</com.example.calendar.DayView> 

तो मैं:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <declare-styleable name="DayView"> 
     <attr name="oddMonth" format="boolean"/> 
    </declare-styleable> 
</resources> 

तो मैं एक कस्टम दृश्य है:

यहाँ मेरी attrs.xml, जिसमें मैं नाम "oddMonth" है, जो बूलियन है के साथ एक विशेषता की घोषणा है लाइन "एंड्रॉयड: पृष्ठभूमि =" डाल @ drawable/dayview_state "" है, जो फाइल करने के लिए संदर्भित करता है dayview_state.xml:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:easycalendar="http://schemas.android.com/apk/res/com.example.calendar"> 

    <item easycalendar:oddMonth ="true" android:drawable="@drawable/customborder_odd" /> 
    <item easycalendar:oddMonth ="false" android:drawable="@drawable/customborder_even"/> 

</selector> 

तो च ar ... जो मैं समझ सकता हूं .... मेरे पास attrs.xml में परिभाषित एक विशेषता है। यह विशेषता मेरे कस्टम दृश्य के लिए राज्य का प्रतिनिधित्व करती है। इस विशेषता के बूलियन मान के मुताबिक मेरा ऐप दो अलग-अलग एक्सएमएल (जो यहां महत्वपूर्ण नहीं हैं) लोड करेगा, प्रत्येक एक अलग ड्रॉइंग को परिभाषित करता है। तो मेरा कस्टम वर्ग बनाने का अंतिम कदम है! कक्षा से एक उद्धरण इस प्रकार है:

public class DayView extends RelativeLayout { 
    private static final int[] STATE_ODD_MONTH = { R.attr.oddMonth }; 
    private boolean mOddmonth = true; 

    public DayView(Context mContext, AttributeSet attrs) { 
     super(mContext, attrs); 
    } 

    @Override 
    protected int[] onCreateDrawableState(int extraSpace) { 
     if (mOddmonth) { 
      final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 
      mergeDrawableStates(drawableState, STATE_ODD_MONTH); 

      return drawableState; 
     } else { 
      return super.onCreateDrawableState(extraSpace); 
     } 
    } 

    public boolean isOddMonth() { 
     return mOddmonth; 
    } 

    public void setOddMonth(boolean oddMonth) { 
     if (mOddmonth != oddMonth) { 
      mOddmonth = oddMonth; 

      refreshDrawableState(); 
     } 
    } 
} 

ठीक है ... इसलिए मैं यहाँ एक निजी चर mOddMonth, गेटर और सेटर whith है। कन्स्ट्रक्टर जिसका उपयोग इस दृश्य को कहीं और बढ़ाने के लिए किया जाता है। एक अन्य निजी चर:

private static final int[] STATE_ODD_MONTH = { R.attr.oddMonth }; 

जो एक सरणी केवल एक पूर्णांक मूल्य से बना है, उस गुण oddMonth attrs.xml में परिभाषित करने के लिए एक संदर्भ है। और विरासत में मिला विधि:

@Override 
    protected int[] onCreateDrawableState(int extraSpace) { 
     if (mOddmonth) { 
      final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 
      mergeDrawableStates(drawableState, STATE_ODD_MONTH); 

      return drawableState; 
     } else { 
      return super.onCreateDrawableState(extraSpace); 
     } 
    } 

जो मैं नहीं कर सकते हैं वास्तव में "गहरा" समझ ... ठीक है, मुझे लगता है कि मैं एक राज्य नहीं जोड़ अगर स्थानीय चर mOddMonth सच है, अन्यथा। तो ... मेरी कोड केवल तभी कारगर साबित मैं निम्नलिखित के साथ मेरी dayview_state.xml बदल देते हैं:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:easycalendar="http://schemas.android.com/apk/res/com.example.calendar"> 

    <item easycalendar:oddMonth ="true" android:drawable="@drawable/customborder_odd" /> 
    <item android:drawable="@drawable/customborder_even"/> 

</selector> 

इस तरह अगर राज्य है पहले लेआउट लोड किया जाता है में, अन्यथा दूसरा एक लोड किया जाएगा। लेकिन राज्य के मूल्य के बारे में क्या? मेरे कोड में कहीं भी मैंने इस चर/विशेषता के लिए मान निर्धारित नहीं किया .... जहां मैं गलत हूं?

+0

ऐसा लगता है कि यह डिफ़ॉल्ट चयनकर्ता के साथ काम कर रहा है और केवल सही मान निर्धारित करता है: <चयनकर्ता xmlns: android = "http://schemas.android। com/apk/res/एंड्रॉयड "> <आइटम एंड्रॉयड: state_pressed =" true " एंड्रॉयड: color =" # ffff0000 "/><- दबाया -> <आइटम एंड्रॉयड: state_focused =" true " एंड्रॉयड : color = "# ff0000ff" /><- ध्यान केंद्रित -> <आइटम एंड्रॉयड:! color = "# ff000000" /><- डिफ़ॉल्ट -> –

+0

और इसलिए? मेरे कस्टम चयनकर्ता के बारे में क्या? – Stefano

+0

मुझे नहीं लगता मैं अपने प्रश्न से प्रति समझते हैं - चर mOddmonth तो thats क्यों आप onCreateDrawableState में STATE_ODD_MONTH राज्य के साथ अंत सही पर सेट किया जाता है। तो "वास्तव में राज्य के मूल्य के बारे में क्या मतलब है?" मेरे कोड में कहीं भी मैंने इस चर/विशेषता के लिए मान निर्धारित नहीं किया है " –

उत्तर

0

मैं तुम्हें b/c यह स्पष्ट नहीं किया गया था जब तक मैं @ kcoppock के जवाब देने के लिए अपनी टिप्पणी है, जो पढ़ आप क्या पूछ रहे थे अपने प्रश्न reword की सिफारिश करेंगे -

"क्या मैं करना चाहता हूँ (या मुझे लगता है कि मुझे करना चाहिए) इस मूल्य को को मेरे कस्टम व्यू, की वास्तविक स्थिति के अनुसार कोड में कहीं भी सेट करना है और फिर इसे फिर से प्रस्तुत करने के लिए मजबूर करना है .... या मुझे नहीं करना चाहिए? "

किसी भी बिंदु पर, आप दृश्य क्वेरी View.getDrawableState का उपयोग कर इसे drawable राज्य पाने के लिए कर सकते हैं।

इस पर आधारित हैं, तो आप अपने drawable फिर से प्रस्तुत करना चाहते हैं, तो आप कई विकल्प हैं।

सबसे पहले आप Drawable.invalidateSelf पर कॉल कर सकते हैं। लेकिन आप शायद ही कभी क्या करने की जरूरत है कि क्योंकि आम तौर पर अपने drawable एक दृश्य की पृष्ठभूमि drawable जो स्वचालित रूप से ड्रा विधि (नहीं OnDraw, जो कि आप क्या आकर्षित) में आप के लिए तैयार की है के रूप में स्थापित किया जाएगा। तो तुम सब उस स्थिति में क्या करने की जरूरत (view.invalidate) दृश्य रद्द करने के लिए है, तो वह आपकी पृष्ठभूमि drawable (इसलिए अपने drawable स्थिति परिवर्तन उठा) पुनः बनाने होंगे।

यदि आप पृष्ठभूमि के रूप में नहीं बल्कि अपने मुख्य ड्राइंग के लिए अपने ड्रॉइंग का उपयोग कर रहे हैं तो आप अपने ड्रॉबल्स को पर ड्रा पर खींचें। एक साधारण myDrawable.draw (कैनवास) पर्याप्त होना चाहिए। लेकिन ऑन ड्रा विधि को ट्रिगर करने के लिए view.invalidate को vall करना याद रखें।

0

आप सही हैं; आप AttributeSet चर के साथ अपने निर्माता में है कि मूल्य को निर्दिष्ट करना होगा:

TypedArray values = context.obtainStyledAttributes(attrs, STATE_ODD_MONTH); 
boolean isOddMonth = values.getBoolean(R.attr.oddMonth, false); 
mOddmonth = isOddMonth; 
values.recycle(); 

मेरा मानना ​​है कि इस चाल करना चाहिए। मैं आम तौर पर एक int [] हार्डकोडिंग के बजाय attrs.xml में एक घोषित-शैली योग्य टैग का उपयोग करता हूं, लेकिन मेरा मानना ​​है कि इसे समान रूप से काम करना चाहिए।

+0

उत्तर के लिए धन्यवाद! अच्छी तरह से ... लेकिन TypedArray विशेषता के मान oddMonth attrs.xml में परिभाषित पुनः प्राप्त करने के लिए इस्तेमाल नहीं कर रहा है? मैं क्या करना चाहता हूं (या मुझे लगता है कि मुझे करना चाहिए) इस कस्टम मूल्य की वास्तविक स्थिति के अनुसार कोड में कहीं भी यह मान सेट करना है, और फिर इसे फिर से प्रस्तुत करने के लिए मजबूर करना .... या मुझे नहीं करना चाहिए? – Stefano

+0

ओह मैं देखता हूं; मेरा मानना ​​है कि मैंने सवाल को गलत समझा, क्षमा करें। – kcoppock

+0

@Stefano नीचे मेरा जवाब देखें। –

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