2010-05-19 7 views
11

मेरे पास एक लेआउट है जो रिश्तेदार आयाम में विजेट के आकार निर्दिष्ट करता है, उदाहरण के लिए:लेआउट की गणना के बाद एंड्रॉइड विजेट का आकार कैसे प्राप्त करें?

<LinearLayout ... layout_height="fill_parent"> 
    <ImageView ... layout_height="wrap_content" /> 
    <TextView ... layout_height="120dp" /> 
</LinearLayout> 

onCreate के तुरंत बाद, मैं जानना चाहता हूं कि ImageView की ऊंचाई कितनी है। उसको कैसे करे?

नोट: अगर मैं onCreate में getHeight() को कॉल करता हूं, तो मुझे 0.

मिलता है। मैंने imageView.postDelayed भी कोशिश की है, यह 2.1 एमुलेटर पर काम करता है लेकिन 1.5 एमुलेटर पर विफल रहता है (मुझे 0 भी मिला है)।

अंत में, मैंने Handler बनाने की कोशिश की, और फिर मैं handler.postDelayed को 10 एमएस देरी के साथ कॉल करता हूं। यह 2.1 और 1.5 एमुलेटर दोनों में काम करता है, लेकिन जब मैं ग्रहण डीबगर में प्रोग्राम शुरू करता हूं तो विफल रहा (इसलिए, मैं निष्कर्ष निकालता हूं कि देरी का उपयोग करने से यह गारंटी नहीं मिलती है कि छविव्यू लेआउट-टेड के बाद ऊंचाई प्राप्त करना होता है।)

उत्तर

11

कारण 0 का आकार प्राप्त करने का कारण यह है कि जब तक गतिविधि पूरी तरह से बनाई जाती है, तब तक लेआउट समाप्त नहीं होता है, यानी क्रिएट(), ऑनस्टार्ट() और ऑनस्यूम() सभी के माध्यम से चले गए हैं। सटीक आकार प्राप्त करने का सबसे आसान तरीका यह है कि लेआउट समाप्त होने के बाद अपनी विधि को कॉल करना है, जैसे कि बटन पर एक क्लिक श्रोता का उपयोग करके। चूंकि लेआउट समाप्त होने तक बटन प्रदर्शित नहीं होता है, तब तक आकार उस समय तक उपलब्ध होना चाहिए जब उसके क्लिक श्रोता को निकाल दिया जाता है।

यह केवल एक अनुमान है, लेकिन मुझे लगता है कि यह ठीक से करना मुश्किल है क्योंकि वे नहीं चाहते हैं कि सिस्टम स्क्रीन को बिछाने के बाद लेआउट आकारों से गड़बड़ कर रहा हो। अगर उन्होंने "ऑनलाउटफिनिश()" कॉलबैक प्रदान किया है, तो आप उसमें लेआउट को संशोधित करते हुए खुद को लूप में फंस सकते हैं। उदाहरण के लिए, कल्पना करें: लेआउट पूरा हो गया है; onLayoutFinished() कहा जाता है और आप वहां लेआउट को संशोधित करते हैं; मौजूदा लेआउट अब अमान्य है; लेआउट फिर से किया; onLayoutFinished() फिर से बुलाया; आपका कोड दोबारा बुलाया जाता है - और बहुत आगे।

ऐसा करने का एक और तरीका कस्टम दृश्य बनाना और onMeasure(int, int) विधि को ओवरराइड करना है। सिस्टम प्रत्येक दृश्य के आकार को प्राप्त करने के लिए उस विधि को ट्रिगर करता है; यदि आप नीचे मेरी उदाहरण की तरह कुछ का उपयोग करें, आप सुझाव आकार से पहले लेआउट समाप्त हो गया है प्राप्त कर सकते हैं:

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){ 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    //getMeasuredHeight() and getMeasuredWidth() now contain the suggested size 
} 

(मैं ने लिखा है कि यह सुझाव दिया आकार है, क्योंकि मुझे लगता है कि यह संभव है आकार के लिए के बाद परिवर्तित करने की यह लेआउट बाधाओं पर आधारित है। हालांकि, यह कुछ समय पहले मैंने जो कुछ पढ़ा था, उसकी अस्पष्ट याददाश्त है, और मैंने कभी भी विस्तार से प्रयोग नहीं किया।) एक बार जब आप इसे कर लेंगे, तो आप आकार के लिए जो कुछ भी करना चाहते हैं उसका उपयोग कर सकते हैं - आप setMeasuredDimension(newX, newY) का उपयोग कर आकार का आकार भी बदल सकता है।

+0

बहुत बहुत धन्यवाद। वह रास्ता लगता है। मैं कोशिश करूँगा। – yuku

+2

यह एक बड़ी बाधा आईएमएचओ है। व्यू या लेआउट को ओवरराइड किए बिना या एक बटन जोड़ने के बिना उपायों को प्राप्त करने में सक्षम नहीं है, जिसकी आपको वास्तव में आवश्यकता नहीं है। –

7

व्यू ऑब्जेक्ट साइज चेंज (int w, int h, int oldw, int oldh) नामक विधि प्रदान करता है। इसे तब कहा जाता है जब लेआउट इसके घटकों में से एक के आकार को बदल देता है। यदि आप इस विधि को ओवरराइड करते हैं तो इस विधि के आपके संस्करण में कोड निम्न स्निपेट में दिखाए गए अनुसार आकार का पता लगाएगा।

@Override 
protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
    bounds = new Rect(); 
    this.getDrawingRect(bounds); 
    // bounds will now contain none zero values 
} 
संबंधित मुद्दे