Android View.getDrawingCache возвращает null, только null

Кто-нибудь попробует объяснить мне, почему

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 drawing cache is null");
  }
  setImageBitmap(child.getDrawingCache()); //TODO MAKE THIS WORK!!!
}

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

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

Спасибо!

Ответ 1

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

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

Ответ 2

Если 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;
}

Ссылка: fooobar.com/questions/49599/...

Ответ 3

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

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

(Вы уже установили "ширину" и "высоту" по своему усмотрению или получили их с помощью WindowManager и т.д.)

Ответ 4

Вместо этого я использую это.

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

Ответ 5

Лучше всего 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);

Ответ 6

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

Ответ 7

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

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

Ответ 8

Я пытаюсь создать количество изображений динамически в зависимости от вида.

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();
}

Я думаю, что этот код поможет кому-то..

Ответ 9

Ошибка может быть вызвана тем, что ваш слишком большой, чтобы вписаться в кеш файл.

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

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

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

Ответ 10

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

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();
    }