2015-05-06 12 views
5

Voglio ottenere uno screenshot "a pagina intera" dell'attività. La vista contiene un RecyclerView con molti elementi.Cattura uno screenshot di RecyclerView a lunghezza COMPLETA

posso prendere una schermata di visualizzazione corrente con questa funzione:

public Bitmap getScreenBitmap() { 
    View v= findViewById(R.id.container).getRootView(); 
    v.setDrawingCacheEnabled(true); 
    v.buildDrawingCache(true); 
    Bitmap b = Bitmap.createBitmap(v.getDrawingCache()); 
    v.setDrawingCacheEnabled(false); // clear drawing cache 
    return b; 
} 

ma contiene solo gli elementi può visionare normalmente (come previsto).

C'è un modo per rendere il RecyclerView magicamente visualizzato in tutta la sua lunghezza (visualizzare tutti gli elementi contemporaneamente) quando faccio lo screenshot?

In caso negativo, come devo affrontare questo problema?

+0

Se si dispone di molti elementi, non importa se la soluzione è possibile, garantisco un errore di memoria insufficiente. –

risposta

7

Qui è la mia soluzione per LinearLayoutManager quando tutti gli articoli sono sulla stessa dimensione e c'è solo un tipo di elemento. Questa soluzione è basata su This answer.

Nota: È possibile che si verifichi un errore di memoria insufficiente.

public static Bitmap getRecyclerViewScreenshot(RecyclerView view) { 
     int size = view.getAdapter().getItemCount(); 
     RecyclerView.ViewHolder holder = view.getAdapter().createViewHolder(view, 0); 
     view.getAdapter().onBindViewHolder(holder, 0); 
     holder.itemView.measure(View.MeasureSpec.makeMeasureSpec(view.getWidth(), View.MeasureSpec.EXACTLY), 
       View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); 
     holder.itemView.layout(0, 0, holder.itemView.getMeasuredWidth(), holder.itemView.getMeasuredHeight()); 
     Bitmap bigBitmap = Bitmap.createBitmap(view.getMeasuredWidth(), holder.itemView.getMeasuredHeight() * size, 
       Bitmap.Config.ARGB_8888); 
     Canvas bigCanvas = new Canvas(bigBitmap); 
     bigCanvas.drawColor(Color.WHITE); 
     Paint paint = new Paint(); 
     int iHeight = 0; 
     holder.itemView.setDrawingCacheEnabled(true); 
     holder.itemView.buildDrawingCache(); 
     bigCanvas.drawBitmap(holder.itemView.getDrawingCache(), 0f, iHeight, paint); 
     holder.itemView.setDrawingCacheEnabled(false); 
     holder.itemView.destroyDrawingCache(); 
     iHeight += holder.itemView.getMeasuredHeight(); 
     for (int i = 1; i < size; i++) { 
      view.getAdapter().onBindViewHolder(holder, i); 
      holder.itemView.setDrawingCacheEnabled(true); 
      holder.itemView.buildDrawingCache(); 
      bigCanvas.drawBitmap(holder.itemView.getDrawingCache(), 0f, iHeight, paint); 
      iHeight += holder.itemView.getMeasuredHeight(); 
      holder.itemView.setDrawingCacheEnabled(false); 
      holder.itemView.destroyDrawingCache(); 
     } 
     return bigBitmap; 
    } 

Nota 2: E 'stato scritto originariamente in Kotlin. Here è il codice originale utilizzato da me.

+2

Facendolo funzionare dove non tutti gli elementi hanno le stesse dimensioni richiederebbe di salvare i dati per ciascun elemento, probabilmente su un file. –

+1

Grazie! Funziona! – davis

+0

La mia una vista testuale non arriva negli screenshot –

10

Ispirato dalla risposta di Yoav. Questo codice funziona per i tipi di oggetto Recyclerview e probabilmente indipendentemente dalle sue dimensioni.

È stato testato con un recyclerview con linearlayout manager e tre tipi di articoli. Ancora per controllarlo con altri gestori di layout.

public Bitmap getScreenshotFromRecyclerView(RecyclerView view) { 
     RecyclerView.Adapter adapter = view.getAdapter(); 
     Bitmap bigBitmap = null; 
     if (adapter != null) { 
      int size = adapter.getItemCount(); 
      int height = 0; 
      Paint paint = new Paint(); 
      int iHeight = 0; 
      final int maxMemory = (int) (Runtime.getRuntime().maxMemory()/1024); 

      // Use 1/8th of the available memory for this memory cache. 
      final int cacheSize = maxMemory/8; 
      LruCache<String, Bitmap> bitmaCache = new LruCache<>(cacheSize); 
      for (int i = 0; i < size; i++) { 
       RecyclerView.ViewHolder holder = adapter.createViewHolder(view, adapter.getItemViewType(i)); 
       adapter.onBindViewHolder(holder, i); 
       holder.itemView.measure(View.MeasureSpec.makeMeasureSpec(view.getWidth(), View.MeasureSpec.EXACTLY), 
         View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); 
       holder.itemView.layout(0, 0, holder.itemView.getMeasuredWidth(), holder.itemView.getMeasuredHeight()); 
       holder.itemView.setDrawingCacheEnabled(true); 
       holder.itemView.buildDrawingCache(); 
       Bitmap drawingCache = holder.itemView.getDrawingCache(); 
       if (drawingCache != null) { 

        bitmaCache.put(String.valueOf(i), drawingCache); 
       } 
//    holder.itemView.setDrawingCacheEnabled(false); 
//    holder.itemView.destroyDrawingCache(); 
       height += holder.itemView.getMeasuredHeight(); 
      } 

      bigBitmap = Bitmap.createBitmap(view.getMeasuredWidth(), height, Bitmap.Config.ARGB_8888); 
      Canvas bigCanvas = new Canvas(bigBitmap); 
      bigCanvas.drawColor(Color.WHITE); 

      for (int i = 0; i < size; i++) { 
       Bitmap bitmap = bitmaCache.get(String.valueOf(i)); 
       bigCanvas.drawBitmap(bitmap, 0f, iHeight, paint); 
       iHeight += bitmap.getHeight(); 
       bitmap.recycle(); 
      } 

     } 
     return bigBitmap; 
    } 
+0

Grazie mille. Mi hai salvato la vita! –

+0

Grazie per il codice, ma imageView non viene esportato –

+0

loro molto grazie, un altro punto possiamo aggiungere frame mobile con quello – Jasss

Problemi correlati