2013-06-13 7 views
5

मेरे पास एक कस्टम व्यू है जिसे मैंने ऑब्जेक्ट आवंटन नहीं करना शुरू किया और मेरे सभी पेंट आवंटन को एक अलग तरीके से ठीक कर दिया।ऑन ड्रा() (स्टेटिकलाउट) में ऑब्जेक्ट आवंटन से बचें?

मुझे कुछ टेक्स्ट के लिए एक स्टेटिकलाइट का उपयोग करने की आवश्यकता है, जिसमें कुछ स्पैन करने योग्य 'सामान' लागू होते हैं।

layoutBpm = new StaticLayout(bpmValue, 
      textPaintBPM, arcRadius, Layout.Alignment.ALIGN_NORMAL, 0, 1, 
      false); 

    layoutBpm.draw(canvas); 

यह मुझे समझने के लिए समझ में आया कि मुझे इस पर से बचने के लिए चेतावनी दी जा रही है। मेरे लिए यह महत्वपूर्ण है कि मैं किसी भी प्रदर्शन के मुद्दों से बचने के लिए जो कुछ भी कर सकता हूं, इसलिए मैं इसे ठीक से करने की कोशिश कर रहा हूं।

मुझे ऐसा कोई प्रलेखन नहीं मिल रहा है जिसे मैं समझ सकता हूं जो बताता है कि स्टेटिकलायआउट के कुछ पैरामीटर वास्तव में क्या करते हैं (फ्लोट स्पेसिंगमल्ट? फ्लोट स्पेसिंगड?), लेकिन तीसरा वाला मुझे लगता है कि स्टेटिकलाउट टेक्स्ट के लिए अधिकतम चौड़ाई है जो मैं केवल मापन से प्राप्त कर सकता हूं क्योंकि यह मेरे कैनवास आकार से संबंधित है। यह मुझे असाइनमेंट ऑन मेजर या ऑन ड्रा में रखना चाहता है, जिसमें से ऐसा लगता है कि मुझे ऐसा करने का मतलब है। क्या StaticLayout असाइनमेंट को ड्रॉ में रखना ठीक है या ऐसा करने का कोई बेहतर तरीका है?

आशा है कि यह समझ में आता है, मैं इसके लिए बहुत नया हूं। हर प्रकार की सहायता के लिए आपका धन्यवाद।

(संपादित करें: मैं एक विधि में इस असाइनमेंट डालने और OnDraw/onMeasure से फोन कर यह मानें कि सिर्फ मूर्ख किया जा रहा है और मुझे चेतावनी ग्रहण बंद हो जाएगा लेकिन अभ्यस्त वास्तव में मदद)

उत्तर

5

चेतावनी के लिए कारण है क्योंकि, बहुत है अक्सर, आपको ड्रॉ ऑपरेशन में ऑब्जेक्ट को कई बार फिर से बनाने की आवश्यकता नहीं होती है। को View में अन्य विधियों की तुलना में सैकड़ों बार बुलाया जा सकता है। अधिकांश समय, वस्तुओं को पुनर्निर्मित किया जा रहा है सटीक मानकों के साथ पुनर्निर्मित किया जा रहा है। दूसरी बार, यह एक ऑब्जेक्ट की स्थिति को बदलने के लिए एक ऑब्जेक्ट की स्थिति को बदलने के लिए बस कम ओवरहेड है।

StaticLayout के मामले में, पाठ बदलने पर या जब आप पैडिंग, स्पेसिंग या मैक्सविड्थ समायोजित करते हैं तो आपको केवल एक नया निर्माण करने की आवश्यकता होती है। यदि पाठ अक्सर बदलता है, तो आप DynamicLayout पर विचार करना चाहेंगे जो हर बार खुद को पुनः प्राप्त करेगा। एक नया ऑब्जेक्ट बनाने से अधिक लागत को पुनर्जीवित करना, लेकिन onDraw() कॉल से अधिक बार ऐसा नहीं होता है।

यदि टेक्स्ट अक्सर नहीं बदलता है और आपको बिल्कुल एक स्टेटिकलाउट का उपयोग करना होगा, तो आप इस संरचना की तरह कुछ प्राप्त कर सकते हैं।

StaticLayout myLayout; 
String textSource = defaultSource; 
Paint textPaint = defaultPaint; 
int textWidth = defaultWidth; 

public CustomView(Context ctx) { 
    super(ctx); 
    createLayout(); 
} 

public void setText(String text) { 
    textSource = text; 
    createLayout(); 
} 

public void setWidth(int width) { 
    textWidth = width; 
    createLayout(); 
} 

@Override 
public void onDraw(Canvas canvas) { 
    myLayout.draw(canvas); 
} 

private void createLayout() { 
    myLayout = new StaticLayout(textSource, textPaint, textWidth, Layout.Alignment.ALIGN_NORMAL, 0, 1, false); 
} 

असल में, जब आप कुछ बदलते हैं तो आप केवल एक नया लेआउट बनाते हैं। अन्यथा आपने जो अंतिम वस्तु बनाई है उसका पुन: उपयोग करें।

EDIT:

एक तरह से एक उपाय पास छोड़ नव आकार दिया दृश्य पर ही View#measure कॉल करने के लिए है। तो आपकी createLayout() विधि इस तरह कुछ होगी।

private void createLayout() { 
     myLayout = new StaticLayout(textSource, textPaint, textWidth, Layout.Alignment.ALIGN_NORMAL, 0, 1, false); 
     int textWidthSpec = MeasureSpec.makeMeasureSpec(maxLayoutWidth, MeasureSpec.AT_MOST); 
     int textHeightSpec = MeasureSpec.makeMeasureSpec(maxLayoutHeight, MeasureSpec.AT_MOST); 
     myLayout.measure(textWidthSpec, textHeightSpec); 
     forceLayout(); 
    } 

असल में यह क्या करता है लेआउट को अधिकतम दृश्य दिखाई देता है। यह खुद और उसके बच्चों को माप देगा। बल Layout() माता-पिता (आपका कस्टम व्यू) पर लागू किया जाएगा जो नए मापों के आधार पर अन्य सामग्री को फिर से लेआउट करेगा।

मुझे ध्यान रखना चाहिए कि मैंने कभी भी स्टेटिकलाउट के साथ ऐसा नहीं किया है, इसलिए मुझे नहीं पता कि क्या होगा। ऐसा लगता है कि दृश्य के निर्माण के समय इस प्रकार के माप को पहले ही संभाला जा सकता है, लेकिन शायद नहीं।

मुझे उम्मीद है कि इससे मदद मिलती है।

+0

धन्यवाद, इसने मुझे चीजों को देखने के लिए थोड़ा नया रास्ता दिया। उपरोक्त को लागू करने वाला एकमात्र मुद्दा यह है कि 'टेक्स्टपेंट' पहले से ही कॉल किया जा रहा है (टेक्स्ट को कैनवास आकार के अनुसार स्केल किया गया है) पर निर्भर करता है और इसलिए 'टेक्स्टविड्थ' भी होता है (जो यह निर्धारित करता है कि टेक्स्ट कब लपेट जाएगा), इसलिए मैं पहले देखने के लिए निर्माता में 'createLayout() 'नहीं कर सकता। मैं इसे 'ऑनमेजर()' में डाल सकता हूं जिसे मैं समझता हूं अक्सर इतनी बार नहीं कहा जाता है? – Anthony

+0

पाठ वास्तव में बहुत कम बदलता है, जिस दृश्य पर मैं काम कर रहा हूं वह वास्तव में एक गोलाकार सेकबार है जिसे मैंने बनाया है और स्टेटिकलाउट का उपयोग बीच में पाठ के लिए किया जाता है जो सेकरबार की प्रगति से संबंधित है। जैसे कि जब आप सर्कल के चारों ओर अपनी अंगुली खींचते हैं तो मूल्य लगातार बदल जाता है। मैंने सोचा कि हालांकि मूल्य बहुत बदलता है, लंबाई हमेशा तीन अंकों तक गद्देदार होती है, इसलिए लेआउट को आकार में समायोजित करने की आवश्यकता नहीं होती है और इसलिए स्टेटिकलाइट ठीक रहेगा। मुझे स्टेटिक/डायनामिक लेआउट पर बहुत कम दस्तावेज मिल सकता है, इसलिए मुझे यकीन नहीं है कि यह सही है या नहीं। किसी भी मदद की सराहना की। – Anthony

+0

तो आखिर में (मुझे लगता है), मैंने 'ऑनमेज चेंज()' के साथ 'ऑनमेज() 'को बदल दिया है क्योंकि मेरी लेआउट आवश्यकताएं सरल हैं और शुरुआती कॉल को' createMayout()' के बजाय 'createLayout() 'में डाल रही हैं। लिंट कुछ कारणों से 'ऑनसाइज चेंज()' में ऑब्जेक्ट आवंटन को ध्यान में रखता नहीं है लेकिन इसे 'मेजर() 'में नापसंद करता है। मैं कल्पना करता हूं कि इन दोनों विधियों को एक ही बार कहा जाता है, इसलिए कोई विचार नहीं कि यह एक में क्यों अच्छा है, न कि दूसरे, लेकिन जो भी हो, ठीक है। मेरी मुख्य चिंता 'ऑन ड्रा()' से आवंटित हो रही थी जो मैंने किया है। एक बार फिर धन्यवाद। – Anthony

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