2015-05-06 27 views
5

Tôi muốn có ảnh chụp màn hình "toàn trang" của hoạt động. Khung nhìn chứa RecyclerView với nhiều mục.Chụp ảnh màn hình RecyclerView với độ dài ĐẦY ĐỦ

tôi có thể mất một ảnh chụp màn hình của giao diện hiện tại với chức năng này:

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

Nhưng nó chỉ chứa các mục tôi có thể xem bình thường (như mong đợi).

Có cách nào để làm cho RecyclerView hiển thị kỳ diệu theo chiều dài đầy đủ (hiển thị tất cả các mục cùng một lúc) khi tôi chụp ảnh màn hình không?

Nếu không, tôi nên tiếp cận vấn đề này như thế nào?

+0

Nếu bạn có nhiều mục, cho dù giải pháp là có thể, tôi đảm bảo bạn đã hết lỗi bộ nhớ. –

Trả lời

7

Đây là giải pháp của tôi cho LinearLayoutManager khi tất cả các mục là trên cùng một kích thước và có chỉ có một loại item. Giải pháp này dựa trên This answer.

Lưu ý: Có thể dẫn đến lỗi bộ nhớ.

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

Note 2: Nó đã ban được viết bằng Kotlin. Here là mã ban đầu được tôi sử dụng.

+2

Làm cho nó hoạt động khi không phải tất cả các mục có cùng kích thước sẽ yêu cầu bạn lưu dữ liệu cho mỗi mục, có thể trên một tệp. –

+1

Cảm ơn bạn! Nó hoạt động! – davis

+0

Một văn bản của tôi không xuất hiện trong ảnh chụp màn hình –

10

Lấy cảm hứng từ câu trả lời của Yoav. Mã này hoạt động cho các loại mục recyclerview và có thể không phân biệt kích thước của nó.

Nó đã được thử nghiệm với một recyclerview có linearlayout quản lý và ba loại mục. Tuy nhiên, để kiểm tra nó với các nhà quản lý bố cục khác.

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

Cảm ơn bạn rất nhiều. Bạn đã cứu cuộc đời của tôi! –

+0

Cảm ơn mã, nhưng imageView không được xuất khẩu –

+0

họ rất cảm ơn, một điểm nữa chúng ta có thể thêm khung di động với – Jasss

Các vấn đề liên quan