Android View.getDrawingCache केवल अशक्त देता है


97

क्या कोई मुझे समझाने की कोशिश करेगा कि क्यों

public void addView(View child) {
  child.setDrawingCacheEnabled(true);
  child.setWillNotCacheDrawing(false);
  child.setWillNotDraw(false);
  child.buildDrawingCache();
  if(child.getDrawingCache() == null) { //TODO Make this work!
    Log.w("View", "View child's drawing cache is null");
  }
  setImageBitmap(child.getDrawingCache()); //TODO MAKE THIS WORK!!!
}

हमेशा लॉग करता है कि ड्राइंग कैश शून्य है, और बिटमैप को शून्य करने के लिए सेट करता है?

क्या कैश सेट होने से पहले मुझे वास्तव में दृश्य आकर्षित करना होगा?

धन्यवाद!


1
stackoverflow.com/questions/9791714/… अप्रोच के getDrawingCache()उपयोग View#drawसे बचेंCanvas
योरज

जवाबों:


240

मुझे भी यह समस्या हो रही थी और मुझे यह उत्तर मिला:

v.setDrawingCacheEnabled(true);

// this is the important code :)  
// Without it the view will have a dimension of 0,0 and the bitmap will be null          
v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 
            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight()); 

v.buildDrawingCache(true);
Bitmap b = Bitmap.createBitmap(v.getDrawingCache());
v.setDrawingCacheEnabled(false); // clear drawing cache

1
WebView माप सामग्री के आकार पर निर्भर करता है, इसलिए यदि वेब पेज अभी तक लोड नहीं हुआ है, तो आपको 0. नाप का माप मिलेगा। UNSPECIFIED के बजाय मापने के लिए वास्तविक आकार को मापने की कोशिश करें, जैसे कि मापने की सुविधा।
मार्सियो कोवरे

3
अभी भी माप के साथ null देता है।

एक बड़े पर्याप्त दृष्टिकोण पर, यह मेरे काम नहीं आया। (संभवतः क्योंकि मेरे पास बहुत सीमित मेमोरी संसाधनों वाला फोन है)। CV2 द्वारा नीचे दिए गए जवाब ने मेरे लिए ठीक काम किया।
साइमन फोर्सबर्ग

@nininho कैसे getdrawingchache () पद्धति का उपयोग किए बिना इमेजव्यू से ड्रा करने योग्य है?
गॉर्जियस_डॉयरवाइरस

यह अच्छा काम करता है। लेकिन यह यूआई में प्रभावित करता है। कृपया इस समस्या को हल करने में मदद करें।
विवेक रवि

58

अगर getDrawingCacheहमेशा returning nullलोग होते हैं: इसका उपयोग करें:

public static Bitmap loadBitmapFromView(View v) {
     Bitmap b = Bitmap.createBitmap( v.getLayoutParams().width, v.getLayoutParams().height, Bitmap.Config.ARGB_8888);                
     Canvas c = new Canvas(b);
     v.layout(0, 0, v.getLayoutParams().width, v.getLayoutParams().height);
     v.draw(c);
     return b;
}

संदर्भ: https://stackoverflow.com/a/6272951/371749


1
अच्छा था। यह एक मेरे लिए काम करता था जबकि अन्य नहीं करते थे। क्या getLayoutParamsv.getWidth () और v.getHeight () के बजाय मानों का उपयोग करने का कोई कारण है ?
साइमन फोर्सबर्ग

क्षमा करें, व्यक्तिगत रूप से, आपके प्रश्न में आपकी सहायता नहीं कर सकता: '(-> अच्छा है कि यह काम किया :)
cV2

@ cV2 मुझे चित्रों पर ड्राइंग मिला, लेकिन मुझे रनिंग सरफेसव्यू पर हटने की आवश्यकता है .. तो मैं आगे क्या कर सकता हूं?
भव्य_डॉयरविरस

4
मुझे अपवाद की चौड़ाई मिल रही है और ऊँचाई होनी चाहिए> 0 ………………………… निजी शून्य takeScreenShot () {for (int i = 1; मैं <4; i ++) {// startDialog (); दृश्य देखें = ScreenShotActivity.this.findViewById (R.id.relativelayout); बिटमैप बिटमैप = loadBitmapFromView (देखें);}}
akash yadav

2
मुझे लगता है कि 'अपवाद की चौड़ाई और ऊंचाई होनी चाहिए> 0` तब आती है जब आपकी ImageViewछवि अभी तक नहीं मिली है, इसलिए ऐसा प्रतीत होता है कि 0. यह अलग-अलग लोगों के कोड के लिए अलग-अलग तरीके से चलेगा, लेकिन सुनिश्चित करें कि आपका कॉल loadBitmapFromView()निश्चित रूप से बाद में है आपकी ImageViewछवि शामिल है
Azurespot

6

मूल कारण किसी को अशक्त होना है कि दृश्य मंद नहीं है। View.getWidthCache () और view.buildDrawingCache () सहित, view.getWidth (), view.getLayoutParams () चौड़ाई आदि का उपयोग करके सभी प्रयास तब बेकार हो जाते हैं। इसलिए, आपको सबसे पहले दृश्य में आयाम सेट करने की आवश्यकता है, जैसे:

view.layout(0, 0, width, height);

(आपने पहले से ही 'चौड़ाई' और 'ऊँचाई' निर्धारित कर दी है, जैसे कि आप उन्हें विंडो मैनजर इत्यादि के साथ पसंद करते हैं या प्राप्त करते हैं।


रूट देखें = curActivity.getWindow ()। GetDecorView ()। FindViewById (android.R.id.content); root.setDrawingCacheEnabled (सही); root.layout (0, 0, 480, 854); mBitmap = root.getDrawingCache ();
नरेंद्र गुसाईं

4

मैं इसके बजाय का उपयोग कर रहा हूँ।

myView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            Bitmap bitmap = Bitmap.createBitmap(myView.getDrawingCache());
        }
    });

3

सबसे अच्छा काम 4me

    Bitmap bitmap = Bitmap.createBitmap( screen.getMeasuredWidth(), screen.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    screen.layout(0, 0, screen.getMeasuredWidth(), screen.getMeasuredHeight());
    screen.draw(canvas);

2

यदि आप जिस दृश्य को पकड़ना चाहते हैं वह वास्तव में स्क्रीन पर दिखाता है, लेकिन यह अशक्त है। इसका मतलब है कि विंडो प्रबंधक द्वारा उत्पन्न करने से पहले आप दृश्य को पकड़ सकते हैं। कुछ लेआउट बहुत जटिल हैं। यदि लेआउट में नेस्टेड लेआउट, लेआउट_वेट..एटीसी शामिल है, तो यह वास्तव में आकार प्राप्त करने के लिए कई बार रिलेआउट करता है। सबसे अच्छा समाधान विंडो मैनेजर के काम खत्म होने तक इंतजार करना और फिर स्क्रीन शॉट प्राप्त करना है। हैंडलर में getDrawingCache () लगाने की कोशिश करें।


1

@ cV2 और @ Nininho के जवाब दोनों मेरे लिए काम करते हैं।

अन्य कारणों में से जो मुझे कठिन लगता है, वह यह था कि मेरे पास जो दृश्य था, वह एक ऐसा दृश्य उत्पन्न कर रहा था, जिसकी चौड़ाई और ऊँचाई 0 है ( यानी एक खाली स्ट्रिंग के स्ट्रिंग पाठ के साथ एक टेक्स्टव्यू होने की कल्पना करें )। इस मामले में, getDrawingCache अशक्त हो जाएगा, इसलिए उसके लिए जांच करना सुनिश्चित करें। आशा है कि वहाँ कुछ लोगों को मदद करता है।


1

त्रुटि ड्राइंग कैश में फिट होने के लिए आपके दृश्य को बहुत बड़ा कर सकती है

मुझे अपने लॉग से मेरे "View.getDrawingCache रिटर्न अशक्त" समस्या का विवरण मिला:

W/View: View too large to fit into drawing cache, needs 19324704 bytes, only 16384000 available

एंड्रॉइड डॉक्स यह भी कहता है : एंड्रॉइड डिवाइसेस में 16MB तक की छोटी मेमोरी हो सकती है जो किसी एक एप्लिकेशन पर उपलब्ध है। यही कारण है कि आप बड़े बिटमैप को लोड नहीं कर सकते हैं।


1

मैं गतिशील रूप से दृश्य के आधार पर छवियों की संख्या बनाने की कोशिश कर रहा हूं।

LayoutInflater infalter=(LayoutInflater)getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View addview=infalter.inflate(R.layout.barcode_image_list_row_item, null);
final ImageView imv=(ImageView) addview.findViewById(R.id.imageView1);
final TextView tv=(TextView) addview.findViewById(R.id.textView1);

try {         
    final Bitmap bitmap = encodeAsBitmap(""+value, BarcodeFormat.CODE_128, 600, 300);

    if (bitmap != null) {
        // TODO Auto-generated method stub
        imv.setImageBitmap(bitmap);
        tv.setText(value);

        addview.setDrawingCacheEnabled(true);

        // this is the important code :)  
        // Without it the view will have a dimension of 0,0 and the bitmap will be null          
        addview.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 
                        MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
        addview.layout(0, 0, addview.getMeasuredWidth(), addview.getMeasuredHeight()); 

        addview.buildDrawingCache(true);
        Bitmap b = Bitmap.createBitmap(addview.getDrawingCache());
        addview.setDrawingCacheEnabled(false); // clear drawing cache
        // saving the bitmap   
        savebarcode(b,value);
    }
} catch (WriterException e) {
    e.printStackTrace();
}

मुझे लगता है कि यह कोड किसी की मदद करेगा ।।


-1

बिटमैप प्राप्त करने का यह सरल और कुशल तरीका है

public void addView(View v) {
        v.setDrawingCacheEnabled(true);
        v.buildDrawingCache();

        Bitmap bitmap = v.getDrawingCache();

        if(bitmap == null) {
            // bitmap is null
            // do whatever you want
        } else {
            setImageBitmap(bitmap);
        }
        v.setDrawingCacheEnabled(false);
        v.destroyDrawingCache();
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.