2010-06-01 12 views
14

मेरे पास एक कस्टम दृश्य है जो मेरी पूरी स्क्रीन भरता है। (एक पियानो कीबोर्ड) जब कोई उपयोगकर्ता कुंजी को छूता है, तो यह invalidate() कहलाता है और पूरे कीबोर्ड को स्पर्श किए गए कुंजी के साथ नया राज्य दिखाने के लिए फिर से खींचा जाता है।एंड्रॉइड: आंशिक रूप से फिर से निकालने के लिए कस्टम दृश्य कैसे प्राप्त करें?

वर्तमान में दृश्य बहुत आसान है, लेकिन मैं थोड़ा और अच्छा ग्राफिक्स जोड़ने की योजना बना रहा हूं। चूंकि पूरा कीबोर्ड गतिशील रूप से प्रस्तुत किया जाता है, इसलिए यह पूरे कीबोर्ड को अधिक महंगा बना देगा।

तो मैंने सोचा, आंशिक पुनर्विचार में देखें। अब मैं सही गंदे क्षेत्र के साथ invalidate(Rect dirty) पर कॉल करता हूं। मैंने अपने onDraw(Canvas canvas) विधि को केवल गंदे क्षेत्र में चाबियाँ खींचने के लिए सेट किया है यदि मैं वास्तव में आंशिक रेड्रा चाहता हूं। इसके परिणामस्वरूप उन चाबियाँ खींची जा रही हैं, लेकिन शेष कीबोर्ड पूरी तरह से काला/बिल्कुल तैयार नहीं है।

क्या मुझे उम्मीद है कि invalidate(Rect dirty) पर कॉल करना वर्तमान canvas "कैश" करेगा, और केवल गंदे क्षेत्र में ड्राइंग करने की अनुमति देता है?

क्या कोई तरीका है जो मैं प्राप्त कर सकता हूं? (एक तरह से करने के लिए "कैश" कैनवास और केवल गंदा क्षेत्र पुनः बनाने "

उत्तर

18

वर्तमान अच्छा समाधान का मैन्युअल रूप से एक बिटमैप के लिए पूरा कैनवास कैश करने के लिए है:

private void onDraw(Canvas canvas) 
{ 
    if (!initialDrawingIsPerformed) 
    { 
      this.cachedBitmap = Bitmap.createBitmap(getWidth(), getHeight(), 
      Config.ARGB_8888); //Change to lower bitmap config if possible. 
      Canvas cacheCanvas = new Canvas(this.cachedBitmap); 
      doInitialDrawing(cacheCanvas); 
      canvas.drawBitmap(this.cachedBitmap, 0, 0, new Paint()); 
      initialDrawingIsPerformed = true; 
    } 
    else 
    { 
      canvas.drawBitmap(this.cachedBitmap, 0, 0, new Paint()); 
      doPartialRedraws(canvas); 
    } 
} 

बेशक, आप की जानकारी स्टोर करने के लिए की जरूरत है अपने आप को फिर से निकालना और अधिमानतः नए Paint का उपयोग नहीं करना चाहिए, लेकिन यह विवरण हैं।

यह भी ध्यान दें: बिटमैप आपके ऐप के मेमोरी उपयोग पर काफी भारी हैं। जब मैंने एक व्यू कैश किया था तो मुझे क्रैश हो गया था एक स्क्रोलर और यह डिवाइस की ऊंचाई 5 गुना की तरह था, क्योंकि इसका उपयोग> 10 एमबी मेमोरी था!

+1

हम्म, मुझे इस solutnio पसंद नहीं है क्योंकि उसकी चाबियाँ आंशिक रूप से खींची गई हैं क्योंकि उसे पहले अपने कैनकवास का पूरा ड्रॉ होना चाहिए। सवाल यह है कि क्यों उनके कैनवास पहले स्थान पर सही ढंग से नहीं खींचे। –

+1

मुझे यह ध्यान रखना होगा कि अब मैं समझता हूं कि जब आप गंदे 'रेक्ट 'के साथ' अमान्य 'कहते हैं, तो आप केवल अपने सामान्य ड्राइंग कोड का उपयोग कर सकते हैं, और इसे केवल गंदे' रेक्ट' में ड्राइंग ऑपरेशंस करना चाहिए। 'कैनवास' 'रेक्ट' के बाहर के संचालन को त्याग देता है। फिर भी, इसका मतलब है कि आपका बहुत से कोड अभी भी प्रस्तुत करता है और एचडब्ल्यू त्वरण के साथ मेरे परीक्षणों में यह पूरी तरह से दृश्य को प्रस्तुत करने से धीमा था। – Peterdk

+1

ध्यान दें कि कैनवास में बिटमैप्स ड्राइंग के लिए पेंट पैराम शून्य हो सकता है, उदा। 'canvas.drawBitmap (बिटमैप, 0, 0, शून्य)'। – greg7gkb

5

पीटरडक के उत्तर के पूरक के लिए, आप बिटमैप के बजाय अपने परिचालन को चित्र में सहेज सकते हैं।

  • एक बिटमैप, सभी पिक्सल बचाने की तरह उन्होंने कहा कि यह स्मृति का एक बहुत ले सकता है जाएगा।
  • एक पिक्चर drawRect, drawLine, आदि जैसे, कॉल की बचत होगी

यह क्या वास्तव में अपने आवेदन में भारी है की निर्भर करता है: ड्रॉ क्रियाकलाप का एक बहुत, कुछ आपरेशन आकर्षित लेकिन भारी गणना द्वारा नियंत्रित , बहुत खाली/अप्रयुक्त स्थान (चित्र पसंद करते हैं) इत्यादि ...

+0

अच्छा, इसमें देखेंगे! – Peterdk

+0

क्षमा करें। क्या 'पिक्चर' रिकॉर्ड 'ड्रॉ बिटमैप (बिटमैप)' कॉल होगा? शायद नहीं, है ना? – Yeung

+0

ध्यान दें कि चित्र प्लेबैक केवल सॉफ्टवेयर कैनवस पर समर्थित है, इसलिए आप इसका उपयोग करने वाले विचारों के लिए हार्डवेयर परतों का उपयोग नहीं कर सकते हैं। – greg7gkb

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