2010-05-10 3 views
96

Я попытаюсь объяснить, что именно мне нужно сделать.Преобразование представления в растровое изображение без отображения его в Android?

У меня есть 3 отдельных экрана: A, B, C. Существует еще один экран, называемый HomeScreen, где все 3 растровые изображения экрана должны отображаться в виде галереи, и пользователь может выбрать, в каком виде он хочет идти.

Мне удалось получить растровые изображения всех трех экранов и отобразить их в окне галереи, поместив весь код только в функцию HomeScreen. Теперь это сильно усложнило код, и я хотел бы его упростить.

Итак, могу ли я вызвать другое действие с HomeScreen и не отображать его и просто получить растровое изображение этого экрана. Например, скажем, я просто вызываю HomeScreen и вызывает Activity A, B, C, и ни одна из Деяний из A, B, C не отображается. Он просто дает растровое изображение этого экрана с помощью getDrawingCache(). И тогда мы можем отображать эти растровые изображения в виде галереи в HomeScreen.

Надеюсь, я очень четко объяснил проблему.

Пожалуйста, дайте мне знать, если это действительно возможно.

+4

На самом деле, я был в состоянии сделай это. – sunil

+1

Я не совсем уверен, но я думаю, вы не сможете этого сделать. Проблема в том, что действия должны отображаться пользователю. Вы можете запустить эту операцию, а затем сразу же скрыть ее, но действие все равно будет отображаться пользователю в течение секунды. Это показано достаточно долго, чтобы его можно было заметить, так как несколько раз мерцание экрана делает приложение непрофессиональным. Тем не менее, возможно, что есть команда запускать деятельность без ее отображения; Я просто не знаю одного, если он существует. –

+0

Здравствуйте, Если вы получите решение, можете ли вы мне помочь? – Kalpesh

ответ

157

есть способ сделать это. вам нужно создать растровое изображение и холст и вызвать view.draw (canvas);

вот код:

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(v.getLeft(), v.getTop(), v.getRight(), v.getBottom()); 
    v.draw(c); 
    return b; 
} 

если вид не отображался до размер его будет равен нулю. Ее можно измерить так:

if (v.getMeasuredHeight() <= 0) { 
    v.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 
    Bitmap b = Bitmap.createBitmap(v.getMeasuredWidth(), v.getMeasuredHeight(), Bitmap.Config.ARGB_8888); 
    Canvas c = new Canvas(b); 
    v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight()); 
    v.draw(c); 
    return b; 
} 

EDIT: согласно this post, WRAP_CONTENT Passing в качестве значения для makeMeasureSpec() не делать ничего хорошего (хотя для некоторых классов представления он делает работу), и рекомендуемое метод:

// Either this 
int specWidth = MeasureSpec.makeMeasureSpec(parentWidth, MeasureSpec.AT_MOST); 
// Or this 
int specWidth = MeasureSpec.makeMeasureSpec(0 /* any */, MeasureSpec.UNSPECIFIED); 
view.measure(specWidth, specWidth); 
int questionWidth = view.getMeasuredWidth(); 
+0

Я пробовал это, но все, что я получаю, - это полупрозрачный черный ящик. Мне нужно что-то сделать в представлении, чтобы подготовить его к рисованию растровых изображений? – Bobbake4

+4

Мне действительно пришлось изменить это на 'v.layout (v.getLeft(), v.getTop(), v.getRight(), v.getBottom());', чтобы заставить это работать правильно, но спасибо за code :) – triad

+2

Мне пришлось использовать v.getWidth() вместо v.getLayoutParams(). width и аналогичный для height. В противном случае, теперь работаем. –

19

вот мое решение:

public static Bitmap getBitmapFromView(View view) { 
    Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888); 
    Canvas canvas = new Canvas(returnedBitmap); 
    Drawable bgDrawable =view.getBackground(); 
    if (bgDrawable!=null) 
     bgDrawable.draw(canvas); 
    else 
     canvas.drawColor(Color.WHITE); 
    view.draw(canvas); 
    return returnedBitmap; 
} 

Наслаждайтесь :)

+0

+1 спасибо за ответ –

+0

Спасибо. У меня были проблемы с некоторыми устройствами, если высота была выше определенного значения. Я не тестировал полностью, но это, похоже, разрешает это. –

19

Попробуйте это,

/** 
     * Draw the view into a bitmap. 
     */ 
     private Bitmap getViewBitmap(View v) { 
      v.clearFocus(); 
      v.setPressed(false); 

      boolean willNotCache = v.willNotCacheDrawing(); 
      v.setWillNotCacheDrawing(false); 

      // Reset the drawing cache background color to fully transparent 
      // for the duration of this operation 
      int color = v.getDrawingCacheBackgroundColor(); 
      v.setDrawingCacheBackgroundColor(0); 

      if (color != 0) { 
       v.destroyDrawingCache(); 
      } 
      v.buildDrawingCache(); 
      Bitmap cacheBitmap = v.getDrawingCache(); 
      if (cacheBitmap == null) { 
       Log.e(TAG, "failed getViewBitmap(" + v + ")", new RuntimeException()); 
       return null; 
      } 

      Bitmap bitmap = Bitmap.createBitmap(cacheBitmap); 

      // Restore the view 
      v.destroyDrawingCache(); 
      v.setWillNotCacheDrawing(willNotCache); 
      v.setDrawingCacheBackgroundColor(color); 

      return bitmap; 
     } 
+0

Это было сделано из коробки, спасибо! – muetzenflo

+0

@muetzenflo приветствую друга !!! –

+0

Как я могу использовать его из класса основной деятельности? – Si8

10

Я знаю, что это может быть несвежий вопрос, но я возникли проблемы с получением какой-либо из этих решений работать на меня. В частности, я обнаружил, что если какие-либо изменения были внесены в представление после того, как он был завышен, эти изменения не будут включены в обработанное растровое изображение.

Вот метод, который в конечном итоге работал для моего дела. Однако с одной оговоркой. до звонка getViewBitmap(View) Я раздул свое мнение и спросил его о макете с известными размерами. Это было необходимо, так как мой макет представления делал бы его нулевой высотой/шириной, пока контент не будет размещен внутри.

View view = LayoutInflater.from(context).inflate(layoutID, null); 
//Do some stuff to the view, like add an ImageView, etc. 
view.layout(0, 0, width, height); 

Bitmap getViewBitmap(View view) 
{ 
    //Get the dimensions of the view so we can re-layout the view at its current size 
    //and create a bitmap of the same size 
    int width = view.getWidth(); 
    int height = view.getHeight(); 

    int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY); 
    int measuredHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY); 

    //Cause the view to re-layout 
    view.measure(measuredWidth, measuredHeight); 
    view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); 

    //Create a bitmap backed Canvas to draw the view into 
    Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 
    Canvas c = new Canvas(b); 

    //Now that the view is laid out and we have a canvas, ask the view to draw itself into the canvas 
    view.draw(c); 

    return b; 
} 

"Магия соус" для меня был найдено здесь: https://groups.google.com/forum/#!topic/android-developers/BxIBAOeTA1Q

Приветствия,

Леви

1

Надеется, что это помогает

View view="some view instance";   
view.setDrawingCacheEnabled(true); 
Bitmap bitmap=view.getDrawingCache(); 
view.setDrawingCacheEnabled(false); 
Смежные вопросы