2012-02-08 7 views
10

जब एक कस्टम दृश्य बनाने, मैंने देखा है कि कई लोगों को इस तरह यह करने के लिए लग रहे हैं:क्या मुझे सुपर() या एंड्रॉइड कस्टम व्यू कन्स्ट्रक्टर के लिए यह() कॉल करना चाहिए?

public MyView(Context context) { 
    super(context); 
    // this constructor used when programmatically creating view 
    doAdditionalConstructorWork(); 
} 

public MyView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    // this constructor used when creating view through XML 
    doAdditionalConstructorWork(); 
} 

private void doAdditionalConstructorWork() { 
    // init variables etc. 
} 

इस के साथ मेरी समस्या यह है कि मुझे मेरे चर अंतिम बनाने से रोकता है। निम्नलिखित करने के लिए कोई कारण नहीं है?

public MyView(Context context) { 
    this(context, null); 
    // this constructor used when programmatically creating view 
} 

public MyView(Context context, AttributeSet attrs) { 
    this(context, attrs, 0); 
    // this constructor used when creating view through XML 
} 

public MyView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    // this constructor used where? 
    // init variables 
} 

मैं एक्सएमएल के माध्यम से और कोड के माध्यम से ठीक दृश्य बनाने के लिए कर लिया है, लेकिन मैं अगर वहाँ इस दृष्टिकोण के लिए किसी भी कमियां हैं यकीन नहीं है। क्या यह सभी मामलों में काम करेगा?

वहाँ another part to this question

+0

कॉलिंग 'यह' वर्तमान कक्षा के दूसरे निर्माता को आमंत्रित करता है। मुझे लगता है कि यह ऐसा कुछ है जिसे आप महसूस नहीं करते थे। इस प्रकार 'यह (संदर्भ, शून्य); 'सार्वजनिक' MyView (संदर्भ संदर्भ, विशेषता एसईटी) कॉल करता है {' जो बदले में 'सार्वजनिक MyView (संदर्भ संदर्भ, विशेषता सेट्स, int defStyle) {'। यह कन्स्ट्रक्टर इनवेशन जावा भाषा में बहुत आम नहीं है, लेकिन मुझे कोई कारण नहीं दिखता है कि यह काम नहीं करेगा। –

+0

मुझे एहसास हुआ कि, मैं सिर्फ पैरामीटर के बारे में चिंतित था। :) –

उत्तर

-5

यह ठीक है।

जब हम TextView.java के स्रोत को देखो।

वे एक ही पदानुक्रम का इस्तेमाल किया है।

तो तुम इस दृष्टिकोण के साथ ठीक कर रहे हैं।

+0

लोग इसे वोट देने के नीचे, कृपया कारण का भी उल्लेख करें। मैंने एंड्रॉइड के अपने कार्यान्वयन संदर्भ को भी जोड़ा है। ओपी के दिए गए परिदृश्य के साथ यह उत्तर सही है। –

-2

हाँ, कि इतने उपयोग करने के लिए आपको बस इतना अपने कंस्ट्रक्टर्स में से हर एक में कस्टम काम दोहराना नहीं एक उचित पद्धति है। और नहीं, विधि में कोई कमी नहीं दिखती है।

-2

यह पूरी तरह से आपकी आवश्यकता पर निर्भर करता है। आइए हम कहें कि क्या आप अपने कस्टम व्यू में अपनी कार्यक्षमता को ओवरराइड किए बिना मूल वर्ग में किसी भी तरीके का उपयोग करना चाहते हैं, तो आपको सुपर() और पैरेंट क्लास को तत्काल उपयोग करने की आवश्यकता है। यदि आपको मूल वर्ग में किसी भी तरीके का आह्वान करने की आवश्यकता नहीं है, तो सभी कार्यान्वयन आपके कस्टम व्यू में ओवरराइड किए गए हैं, तो आपको इसकी आवश्यकता नहीं है। पढ़ें में एक कस्टम व्यू उदाहरण अनुभाग।

7

एकमात्र कमी जो मैं देख सकता हूं (जिसे कोई भी उल्लेख नहीं किया गया है) यह है कि आपका दूसरा कन्स्ट्रक्टर सुपरक्लास के defStyle खो देता है, क्योंकि आप इसे शून्य पर सेट करते हैं। किसी भी एंड्रॉइड के व्यू क्लास के लिए सोर्स कोड देखें, और आप देखेंगे कि दूसरे कन्स्ट्रक्टर में हमेशा एक विशिष्ट defStyle परिभाषित किया गया है। ,

public ListView(Context context, AttributeSet attrs) { 
    this(context, attrs, com.android.internal.R.attr.listViewStyle); 
} 

आप दूसरा दृष्टिकोण है कि आप का वर्णन का उपयोग कर ListView विस्तार करने के लिए थे, तो com.android.internal.R.attr.listViewStyle अब defStyle होगा क्योंकि आप को दरकिनार होगी:

उदाहरण के लिए, इस ListView के दूसरे निर्माता है वह दूसरा सुपर कन्स्ट्रक्टर और इसे शून्य बना देता है। मैं तुम इतनी तरह एक ही defstyle ListView के रूप में उपयोग करते हुए, द्वारा इस को हल कर सकता है लगता है:

public MyView(Context context, AttributeSet attrs) { 
    this(context, attrs, android.R.attr.listViewStyle); 
} 

लेकिन यह वास्तव में "शुद्धतावादी" तरीका नहीं है, क्योंकि आप कृत्रिम रूप से मजबूर कर रहे हैं एक ही defStyle ListView के रूप में है।

तो, दूसरों ने जो कहा, उसके विपरीत, मुझे लगता है कि आप वास्तव में सोचते हैं कि आप अपनी पोस्ट में उल्लिखित पहले doAdditionalConstructorWork() दृष्टिकोण का उपयोग करना बेहतर कर रहे हैं, क्योंकि कम से कम यह सुनिश्चित करता है कि defStyle सही ढंग से सेट है।

+0

लेकिन 'व्यू' स्रोत कोड को देखते हुए हम देख सकते हैं कि ** ** ** ** defStyle' को 0 पर सेट करता है: 'सार्वजनिक व्यू (संदर्भ संदर्भ, विशेषता एसईटी) { यह (संदर्भ, attrs, 0); } ' –

3

एक समान प्रश्न के लिए मेरा उत्तर से कॉपी किया गया।

यदि आप सभी तीन रचनाकारों को ओवरराइड करते हैं, तो कृपया this(...) कॉल्स को कैस्केड न करें। इसके बजाय आप यह कर किया जाना चाहिए:

public MyView(Context context) { 
    super(context); 
    init(context, null, 0); 
} 

public MyView(Context context, AttributeSet attrs) { 
    super(context,attrs); 
    init(context, attrs, 0); 
} 

public MyView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    init(context, attrs, defStyle); 
} 

private void init(Context context, AttributeSet attrs, int defStyle) { 
    // do additional work 
} 

कारण है कि माता-पिता वर्ग का अपना कंस्ट्रक्टर्स कि आप गलती से अधिभावी हो सकता है में डिफ़ॉल्ट गुण शामिल हो सकता है।

public TextView(Context context) { 
    this(context, null); 
} 

public TextView(Context context, @Nullable AttributeSet attrs) { 
    this(context, attrs, com.android.internal.R.attr.textViewStyle); 
} 

public TextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 
    this(context, attrs, defStyleAttr, 0); 
} 

आप super(context) फोन नहीं किया, तो आप नहीं होगा ठीक से R.attr.textViewStyle शैली attr के रूप में स्थापित: उदाहरण के लिए, इस TextView के लिए निर्माता है।

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