Android View.getDrawingCache возвращает ноль, только ноль - PullRequest
93 голосов
/ 26 февраля 2010

Кто-нибудь, пожалуйста, попытайтесь объяснить мне, почему

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

ВСЕГДА регистрирует, что кэш чертежа равен нулю, и устанавливает растровое изображение в ноль?

Нужно ли рисовать вид до того, как установлен кэш?

Спасибо!

Ответы [ 10 ]

233 голосов
/ 06 января 2011

У меня тоже была эта проблема, и я нашел ответ:

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
57 голосов
/ 13 августа 2012

если 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

6 голосов
/ 13 марта 2016

Основная причина получения нулей - это то, что представление не имеет размеров. Тогда все попытки с использованием view.getWidth (), view.getLayoutParams (). Width и т. Д., Включая view.getDrawingCache () и view.buildDrawingCache (), бесполезны. Итак, сначала вам нужно установить размеры для вида, например ::100100

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

(Вы уже установили «ширину» и «высоту» так, как вам нравится, или получили их с помощью WindowManager и т. Д.)

4 голосов
/ 02 июня 2015

Я использую это вместо.

myView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            Bitmap bitmap = Bitmap.createBitmap(myView.getDrawingCache());
        }
    });
2 голосов
/ 21 августа 2016

Лучшая работа 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 голосов
/ 16 мая 2013

Если вид, который вы хотите поймать, действительно отображается на экране, но возвращает ноль. Это означает, что вы ловите представление до того, как оконный менеджер его сгенерирует. Некоторые макеты очень сложны. Если макет включает в себя вложенные макеты, layout_weight..etc, он заставляет несколько раз ретранслировать, чтобы получить точный размер. Лучшее решение - дождаться, пока оконный менеджер завершит работу, а затем сделать снимок экрана. Попробуйте поместить getDrawingCache () в обработчик.

1 голос
/ 13 апреля 2016

Ошибка может быть из-за того, что ваш слишком велик, чтобы поместиться в кэш чертежа .

Я получил объяснение моей проблемы «View.getDrawingCache возвращает null» из моих журналов:

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

Документы Android также говорит : Устройства Android могут иметь всего 16 МБ памяти, доступной для одного приложения. Именно поэтому вы не можете загружать большие растровые изображения.

1 голос
/ 01 апреля 2016

Я пытаюсь создать 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);

            }else{

            }


        } catch (WriterException e) {
            e.printStackTrace();
        }

Думаю, этот код кому-нибудь поможет ..

1 голос
/ 27 июня 2015
Ответы

@ cV2 и @ nininho работают для меня.

Одной из других причин, по которым я выяснил трудный путь, было то, что мое представление генерировало представление с шириной и высотой 0 (, т. Е. Представьте себе TextView со строковым текстом пустой строки). ). В этом случае getDrawingCache вернет значение NULL, поэтому просто проверьте это. Надеюсь, что это поможет некоторым людям.

0 голосов
/ 04 декабря 2017

Это простой и эффективный способ получить растровое изображение

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();
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...