Android View.getDrawingCacheがnullを返し、nullのみ


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!!!
}

常に描画キャッシュがnullであることをログに記録し、ビットマップをnullに設定しますか?

キャッシュが設定される前に実際にビューを描画する必要がありますか?

ありがとう!


1
stackoverflow.com/questions/9791714/…アプローチのgetDrawingCache()使用View#drawを避けるCanvas
Yuraj

回答:


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の測定はコンテンツサイズに依存するため、Webページがまだ読み込まれていない場合は、0のメジャーを取得します。MeasureSpec.makeMeasureSpec(800、MeasureSpec.EXACTLY);のように、UNSPECIFIEDではなく、実際のサイズを渡して測定してみてください。
Marcio Covre

3
MeasureSpec.EXACTLYを使用してもnullを返します。

十分に大きな見方をすると、これは私にはうまくいきませんでした。(おそらく私は非常に限られたメモリリソースを持つ電話を持っているためです)。cV2による以下の答えは私にはうまくいきました。
Simon Forsberg、2013

@nininho getdrawingchache()メソッドを使用せずにimageviewからドローアブルを取得する方法?
Gorgeous_DroidVirus 14年

それはうまくいきます。しかし、UIに影響します。この問題の解決にご協力ください。
Vivek Ravi 2014

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()の代わりにからの値を使用する理由はありますか?
Simon Forsberg、2013

ごめんなさい、個人的にはあなたの質問を手伝うことはできません: '(->うまくいったことを
嬉しく思います

@ cV2画像の描画を取得しましたが、実行中のsurfaceviewでgetdrawingcacheを取得する必要があります。次に何をすればよいですか?
Gorgeous_DroidVirus 14年

4
私は例外の幅と高さを取得している必要があります> .............................. private void takeScreenShot(){for(int i = 1; i <4; i ++){// startDialog(); ビューを表示= ScreenShotActivity.this.findViewById(R.id.relativelayout); ビットマップビットマップ= loadBitmapFromView(view);}}
akash yadav

2
「例外の幅と高さは> 0でなければなりません」はImageView、画像をまだ受け取っていないときに発生するため、0のように見えます。これは、人々のコードによって異なる方法で再生されますが、呼び出しloadBitmapFromView()はあなたImageViewの画像が含まれています。
Azurespot 2015

6

nullを取得する基本的な理由は、ビューが言及されていないためです。次に、view.getDrawingCache()およびview.buildDrawingCache()を含む、view.getWidth()、view.getLayoutParams()。widthなどを使用したすべての試行は役に立たない。したがって、まずビューに寸法を設定する必要があります。例:

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

(すでに「幅」と「高さ」を好きなように設定している、またはWindowManagerなどで取得済みです。)


ルートを表示= currActivity.getWindow()。getDecorView()。findViewById(android.R.id.content); root.setDrawingCacheEnabled(true); root.layout(0、0、480、854); mBitmap = root.getDrawingCache();
Narender Gusain 2017

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

キャッチするビューが実際に画面に表示されているが、nullを返す場合。つまり、ウィンドウマネージャーが生成する前にビューをキャッチします。一部のレイアウトは非常に複雑です。レイアウトにネストされたレイアウト(layout_weight..etc)が含まれている場合、数回の再レイアウトで正確なサイズが取得されます。最良の解決策は、ウィンドウマネージャーがジョブを完了してからスクリーンショットを取得するまで待つことです。ハンドラーにgetDrawingCache()を配置してみてください。


1

@ cV2と@nininhoの回答はどちらもうまくいきます。

私が難しい方法を見つけた他の理由の1つは、私が持っていたビューが幅と高さが0のビューを生成していたことですつまり、空の文字列の文字列テキストを持つTextViewがあると想像してください)。この場合、getDrawingCacheはnullを返すため、必ず確認してください。そこにいる人々を助けることを願っています。


1

このエラーは、ビューが大きすぎて描画キャッシュに収まらないことが原因である可能性があります。

私のログから「View.getDrawingCacheがnullを返す」問題の説明を得ました。

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

Androidのドキュメントに次のようにも記載されています。これが大きなビットマップをロードできない理由です。


1

ビューに基づいて動的にn個の画像を作成しようとしています。

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();
    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.