2012-12-13 10 views
116

मैं थोड़ा View वर्ग के forceLayout(), requestLayout() और invalidate() तरीकों की भूमिकाओं के बारे में संदेह में हूँ।उपयोग) तथा अमान्य()

जब वे कहा जाता है की जाएगी? http://developer.android.com/guide/topics/ui/how-android-draws.html

मेरे लिए invalidate() के लिए एक कॉल केवल देखने के ताज़ा होता है और requestLayout() के लिए एक कॉल दृश्य ताज़ा करता है और स्क्रीन पर देखने के आकार की गणना:

उत्तर

241

बेहतर François BOURLIEUX और Dalvik द्वारा प्रदान की जवाब समझने के लिए मैं सुझाव है कि आप Arpit Mathur द्वारा इस भयानक दृश्य जीवन चक्र चित्र पर एक नज़र लेने के लिए: enter image description here

+20

मैं अक्सर अनुरोध देखता हूं अमान्य होने के बाद सीधे कॉल किया जा रहा है, मैं यह भी देखता हूं कि टेक्स्टव्यू जैसी चीजों के लिए एंड्रॉइड स्रोत कोड में हो रहा है, लेकिन इस आरेख के अनुसार ऐसा करना अनावश्यक है, है ना? तो क्या ऐसा करने का कोई उद्देश्य है? – tcox

+5

वैसे यह एक दिलचस्प सवाल है, और ईमानदार होने के लिए मुझे वास्तव में पता नहीं है कि वे दोनों विधियों को क्यों कहते हैं उदा। 'TextView'। मैंने सोचा कि शायद वे लेआउट से संबंधित पैरामीटर बदलने से पहले आखिरी बार 'व्यू' को आकर्षित करना चाहते हैं, लेकिन अगर हम अलग-अलग ऑर्डर में उन कॉलों के बारे में सोचते हैं तो यह वास्तव में कोई समझ नहीं लेता है (और वे कॉल करते हैं) 'textView' में भी 'अनुरोध Layout()' के बाद भी अमान्य() 'अवैध करें)। शायद यह StackOverflow पर एक और सवाल का हकदार है :)? –

+0

बस ध्यान दें कि ऊपर दिया गया चित्र साफ़ है लेकिन भ्रामक हो सकता है। मेरा मानना ​​है कि अमान्य() दृश्य पदानुक्रम (व्यू रूट का उपयोग करके) पर एक उपाय पास निर्धारित कर सकता है। यदि दृश्य परिवर्तन एक साधारण बीजी रंग परिवर्तन है, तो हमारे पास उपाय पास या प्रदर्शन के बारे में चिंता करने की कोई बात नहीं है। लेकिन अमान्यता कारण उदाहरण के लिए एक आकार परिवर्तन है, तो उपाय पास को भी लात मारना चाहिए और पाइपलाइन चरणों को प्रस्तुत करना अनुरोध के साथ बहुत समान (या बिल्कुल वही होना चाहिए)। – zgulser

23

यहाँ आप कुछ प्रतिक्रिया मिल सकता है।

+3

कैसे forceLayout() तो? – fiddler

+0

@fiddler, इस विधि के बारे में सिर्फ सेट दो झंडे: PFLAG_FORCE_LAYOUT और PFLAG_INVALIDATED – suitianshi

+7

@suitianshi झंडे को सेट करने के क्या परिणाम हैं? – Sergey

3

आप अमान्य() को उस दृश्य पर उपयोग करते हैं जिसे आप फिर से निकालना चाहते हैं, यह इसके ऑन ड्रा (कैनवास सी) को बुलाएगा, और अनुरोध Layout() पूरे लेआउट प्रतिपादन (माप चरण और स्थिति चरण) को फिर से चलाएगा । आप इसे उपयोग करना चाहिए अगर आप क्रम पर है, लेकिन केवल जनक दृश्य से बाधाओं की तरह विशेष मामलों में बच्चे को देखने के आकार को बदल रहे हैं (कि द्वारा मेरा मतलब है कि माता-पिता ऊंचाई या चौड़ाई WRAP_CONTENT हैं और इसलिए बच्चों को मापने से मेल खाते हैं इससे पहले कि वे उन्हें फिर से लपेट कर सकते हैं)

50

invalidate()

कॉलिंग invalidate() किया जाता है जब आप एक समय निर्धारित करना चाहते दृश्य की वापसी। इसके परिणामस्वरूप onDraw परिणामस्वरूप अंततः (जल्द ही, लेकिन तुरंत नहीं) कहा जा रहा है। जब कोई कस्टम व्यू कॉल करेगा तो इसका एक उदाहरण तब होता है जब टेक्स्ट या पृष्ठभूमि रंग की संपत्ति बदल जाती है।

दृश्य फिर से ताज़ा किया जाएगा, लेकिन आकार में परिवर्तन नहीं होगा।

requestLayout()

आपके विचार परिवर्तन के बारे में कुछ ऐसा है जो आकार को प्रभावित करेगा, तो आप requestLayout() फोन चाहिए। यह onMeasure और onLayout माता पिता विचारों के लिए लाइन अप सभी तरह न केवल इस दृश्य के लिए लेकिन ट्रिगर किया जाएगा।

कॉलिंग requestLayout()not guaranteed to result in an onDraw है (स्वीकृत उत्तर में चित्र का क्या अर्थ है) के विपरीत, इसलिए यह आमतौर पर invalidate() के साथ संयुक्त होता है।

invalidate(); 
requestLayout(); 

इसका एक उदाहरण तब होता है जब एक कस्टम लेबल की टेक्स्ट प्रॉपर्टी बदल जाती है। लेबल आकार बदल जाएगा और इस प्रकार remeasured और redrawn की जरूरत है।

forceLayout()

जब वहाँ है एक requestLayout() कि एक माता पिता को देखने के समूह पर कहा जाता है, यह remeasure और अपने बच्चे को देखा गया relayout के लिए नहीं आवश्यक जरूरत है। हालांकि, अगर किसी बच्चे को रिमूजर और रिलेआउट में शामिल किया जाना चाहिए, तो आप बच्चे पर forceLayout() पर कॉल कर सकते हैं। forceLayout() केवल एक बच्चे पर काम करता है अगर यह इसके प्रत्यक्ष माता-पिता पर एक requestLayout() साथ संयोजन के रूप में होता है। forceLayout() को कॉल करके स्वयं का कोई प्रभाव नहीं पड़ेगा क्योंकि यह दृश्य पेड़ को requestLayout() ट्रिगर नहीं करता है।

forceLayout() की एक अधिक विस्तृत विवरण के लिए this Q&A पढ़ें।

इसके अलावा

+0

विस्तृत उत्तर के लिए धन्यवाद। क्या आप इस बारे में थोड़ा और स्पष्टीकरण दे सकते हैं कि 'अनुरोध Layout() को ऑनड() 'के परिणामस्वरूप क्यों गारंटी नहीं है? आप इसके साथ कैसे आए हैं? क्या यह दस्तावेज़ों में उल्लिखित है? – azizbekian

+0

@azizbekian, मैं उस टिप्पणी के लिए अपने स्रोत के बारे में और बात करता हूं [यहां] (https://stackoverflow.com/a/42430021/3681880)। यह दस्तावेज़ नहीं है लेकिन रोमेन गाय एक Google इंजीनियर है और कुछ एंड्रॉइड दस्तावेज लिखता है, मुझे विश्वास है। आप ['देखें 'स्रोत कोड] (https://stackoverflow.com/a/42430021/3681880) भी देख सकते हैं। – Suragch

+0

'forceLayout() 'के बारे में हिस्सा गलत है। विवरण के लिए [मेरा जवाब] (https://stackoverflow.com/a/44781500/1183577) देखें। – fluidsonic

1

This answerforceLayout() के बारे में सही नहीं है।

जैसा कि आप the code of forceLayout() में देख सकते हैं, यह केवल "रिलेआउट की आवश्यकता है" के रूप में दृश्य को चिह्नित करता है लेकिन यह न तो शेड्यूल करता है और न ही उस रिलाउट को ट्रिगर करता है। रिलायआउट भविष्य में किसी बिंदु पर तब तक नहीं होगा जब दृश्य के माता-पिता को किसी अन्य कारण से बाहर रखा गया था। जब forceLayout() और requestLayout() का उपयोग कर

वहाँ भी एक बहुत बड़ा मुद्दा है:

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

मैं forceLayout() के कार्यान्वयन पर विचार चाहते हैं (और यह requestLayout() तोड़ा जा कैसे प्रभावित करता है और आप अपने कोड में है कि समारोह का उपयोग कभी नहीं करना चाहिए।

+1

हाय! कैसे आप उस * वर्तनी * के साथ आते हैं? क्या यह कहीं दस्तावेज है? – azizbekian

+0

दुर्भाग्यवश यह दस्तावेज नहीं है और संभवतः इरादा भी नहीं है। मैंने इसे 'व्यू' के कोड की जांच करके और स्वयं को इस मुद्दे में चलाकर और इसे डिबग करने के द्वारा निकाला। – fluidsonic

+0

फिर मैं 'forceLayout() 'एपीआई के उद्देश्य के बारे में उत्सुक हूं: यह वास्तव में एक लेआउट पास को मजबूर नहीं करता है, बल्कि यह सिर्फ ध्वज को बदलता है [जिसे' मेजर()'] (https: // android 'में देखा जा रहा है। googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/view/View.java#19834), लेकिन 'onMeasure()' को तब तक नहीं बुलाया जाएगा जब तक 'requestLayout() ' या एक स्पष्ट 'देखें # उपाय() 'कहा जाता है। इसका मतलब है कि' forceLayout()' होना चाहिए 'अनुरोध Layout() 'के साथ जोड़ा गया। दूसरी तरफ, अगर मुझे अभी भी 'requestLayout() 'करने की आवश्यकता है तो' forceLayout()' करने के लिए क्यों? – azizbekian

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