Android View.getDrawingCache는 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 측정은 콘텐츠 크기에 따라 달라 지므로 웹 페이지가 아직로드되지 않은 경우 측정 값은 0이됩니다. MeasureSpec.makeMeasureSpec (800, MeasureSpec.EXACTLY);처럼 UNSPECIFIED 대신 측정 할 실제 크기를 전달해보세요.
Marcio Covre

3
MeasureSpec.EXACTLY를 사용하더라도 여전히 null을 반환합니다.

충분히 큰 관점에서 이것은 나를 위해 작동하지 않았습니다. (아마도 메모리 리소스가 매우 제한된 전화기를 가지고 있기 때문일 수 있습니다). cV2의 아래 답변은 저에게 잘 맞았습니다.
사이먼 포스 버그

@nininho getdrawingchache () 메서드를 사용하지 않고 imageview에서 드로어 블을 얻는 방법은 무엇입니까?
Gorgeous_DroidVirus

잘 작동한다. 그러나 그것은 UI에 영향을 미칩니다. 이 문제를 해결하는 데 도움을주세요.
Vivek Ravi

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

@ cV2 이미지에 그림이 있지만 surfaceview를 실행할 때 getdrawingcache를 가져와야합니다. 그러면 다음에 무엇을 할 수 있습니까?
Gorgeous_DroidVirus

4
예외 너비와 높이가> 0 .............................. private void takeScreenShot () {for (int i = 1; i <4; i ++) {// startDialog (); 보기보기 = ScreenShotActivity.this.findViewById (R.id.relativelayout); 비트 맵 맵 = loadBitmapFromView (뷰);}}
아카 쉬 야다 브

2
나는 '0>는'예외 폭과 높이가 있어야합니다 생각 당신이 경우에 대해 오는 ImageView것이이 다른 사람들의 코드를 다르게 연주 할 0으로 나타나도록, 아직 이미지를받지 못한, 그러나에 확인 전화를 확인 loadBitmapFromView()후 확실히 당신 ImageView은 이미지를 포함합니다.
Azurespot

6

null을 얻는 기본적인 이유는 뷰가 언급되지 않았기 때문입니다. 그런 다음 view.getDrawingCache () 및 view.buildDrawingCache ()를 포함하여 view.getWidth (), view.getLayoutParams (). width 등을 사용하는 모든 시도는 쓸모가 없습니다. 따라서 먼저 뷰에 치수를 설정해야합니다. 예 :

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

(원하는대로 '너비'와 '높이'를 이미 설정했거나 WindowManager 등으로 획득했습니다.)


View root = currActivity.getWindow (). getDecorView (). findViewById (android.R.id.content); root.setDrawingCacheEnabled (true); root.layout (0, 0, 480, 854); mBitmap = root.getDrawingCache ();
Narender Gusain

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의 답변은 모두 저에게 효과적입니다.

내가 어려운 방법을 알아 낸 다른 이유 중 하나는 내가 가진 뷰가 너비와 높이가 0 인 뷰를 생성하고 있다는 것입니다 ( 즉, 빈 문자열의 문자열 텍스트가있는 TextView가 있다고 상상해보십시오 ). 이 경우 getDrawingCache는 null을 반환하므로 반드시 확인하십시오. 그것이 어떤 사람들에게 도움이되기를 바랍니다.


1

뷰가 너무 커서 도면 캐시에 맞지 않기 때문에 오류가 발생할 수 있습니다 .

내 로그에서 "View.getDrawingCache returns null"문제에 대한 설명을 받았습니다.

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

안드로이드 문서는 말한다 : 안드로이드 장치가 하나의 응용 프로그램에 사용할 수있는 메모리 16MB의 적은으로 할 수 있습니다. 이것이 큰 비트 맵을로드 할 수없는 이유입니다.


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.