简体   繁体   中英

Take a screenshot of RecyclerView in FULL length .. each item having a list

I am using a recyclerView having lists of dynamic sizes...and when i use this method to take screenshot of each recyclerView item.. it taking the screenshot but each item containing only one list item each.. even if the list item size > 1 .

public static Bitmap getRecyclerViewScreenshot(RecyclerView view) {
    int size = view.getAdapter().getItemCount();
    RecyclerView.ViewHolder holder = view.getAdapter().createViewHolder(view, 0);
    view.getAdapter().onBindViewHolder(holder, 0);
    ArrayList<Bitmap> bitmaps=new ArrayList<>();
    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();
        bitmaps.add(holder.itemView.getDrawingCache());
        bigCanvas.drawBitmap(holder.itemView.getDrawingCache(), 0f, iHeight, paint);
        iHeight += holder.itemView.getMeasuredHeight();
        holder.itemView.setDrawingCacheEnabled(false);
        holder.itemView.destroyDrawingCache();
    }
    return bigBitmap;
}



  Here is my screenshot attached (`of each item of recyclerView`)!! It should show `two items` but uniformly its showing `1 item` each ` I am facing problem with the `inner listView` 

Original is :- 在此处输入图片说明

Screenshot is :- 在此处输入图片说明

Its the case for each and every recycler item screenshot only 1 item is shown.

faced the same issue and resolved this by using this piece of code.

First of all, ask your view to calculate it's measurements and then ask view to give MeasuredHeight and all done.

recyclerView.measure(
        View.MeasureSpec.makeMeasureSpec(recyclerView.getWidth(), View.MeasureSpec.EXACTLY),
        View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));

Bitmap bm = Bitmap.createBitmap(recyclerView.getWidth(), recyclerView.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
recyclerView.draw(new Canvas(bm));

saveImage(bm);
ImageView im
          = new ImageView(getActivity());
im.setImageBitmap(bm);
 new AlertDialog.Builder(getActivity()).setView(im).show();

This might solve the issue,

I have created a Bitmap bmOverlay to draw both bitmaps over this bitmap. Also, I have taken another For loop for creating bitmap for the listview Items.

Here are the Changes I did to your Code:

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

        //Create bitmap to draw both recycler bitmap and listview
        Bitmap bmOverlay = Bitmap.createBitmap(bigBitmap.getWidth(), bigBitmap.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bmOverlay);


        HashMap<Integer, List<Bitmap>> bmp = recommendTestAdapter.getBmp();
        HashMap<Integer, Integer> height = recommendTestAdapter.getHeight();
        HashMap<Integer, Integer> width = recommendTestAdapter.getWidth();

        for (int i = 1; i < size; i++) {
            view.getAdapter().onBindViewHolder(holder, i);
            holder.itemView.setDrawingCacheEnabled(true);
            holder.itemView.buildDrawingCache();
            List<Bitmap> bitmapList = bmp.get(i);
            int allHeight = height.get(i);
            int listViewWidth = width.get(i);

            Bitmap smallBitmap = Bitmap.createBitmap(listViewWidth, allHeight, Bitmap.Config.ARGB_8888);
            Canvas smallCanvas = new Canvas(smallBitmap);

            paint = new Paint();
            int iListHeight = 0;

            for (int j = 0; j < bitmapList.size(); j++) {
                Bitmap bmpList = bitmapList.get(j);
                smallCanvas.drawBitmap(bmpList, 0, iListHeight, paint);
                iListHeight += bmpList.getHeight();

                bmpList.recycle();
            }

            bigCanvas.drawBitmap(holder.itemView.getDrawingCache(), 0f, iHeight, paint);
            bigCanvas.drawBitmap(smallBitmap, 0f, iListHeight, paint);
            iHeight += holder.itemView.getMeasuredHeight();
            holder.itemView.setDrawingCacheEnabled(false);
            holder.itemView.destroyDrawingCache();

            canvas.drawBitmap(bigBitmap, new Matrix(), null);
            canvas.drawBitmap(smallBitmap, new Matrix(), null);
            return bmOverlay;
        }
        return bigBitmap;
    }

Here's my RecycleView Adapter,

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.viewHolder> {

    private Context context;
    private ArrayList<RecyclerData> recyclerData;
    private ListViewAdapter listAdapter;
    private HashMap<Integer, List<Bitmap>> bmp = new HashMap<>();
    private HashMap<Integer, Integer> height = new HashMap<>();
    private HashMap<Integer, Integer> width = new HashMap<>();

    public RecyclerAdapter(Context context, ArrayList<RecyclerData> recyclerData) {
        this.context = context;
        recyclerData = recyclerData;
    }

    @Override
    public viewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recyclerview, parent, false);
        return new viewHolder(view);
    }

    @Override
    public void onBindViewHolder(final viewHolder holder, final int position) {
        listAdapter = new ListViewAdapter(context);
        holder.listView.setAdapter(listAdapter);

        List<Bitmap> bitmapList = new ArrayList<>();
        int allItemsHeight = 0;
        for (int i = 0; i < listAdapter.getCount(); i++) {

            View childView = listAdapter.getView(i, null, holder.listView);
            childView.measure(View.MeasureSpec.makeMeasureSpec(holder.listView.getWidth(), View.MeasureSpec.EXACTLY),
                    View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));

            childView.layout(0, 0, childView.getMeasuredWidth(), childView.getMeasuredHeight());
            childView.setDrawingCacheEnabled(true);
            childView.buildDrawingCache();
            bitmapList.add(childView.getDrawingCache());
            allItemsHeight+=childView.getMeasuredHeight();
        }
        width.put(position, holder.listView.getMeasuredWidth());
        height.put(position, allItemsHeight);
        bmp.put(position, bitmapList);
    }

    public HashMap<Integer, List<Bitmap>> getBmp() {
        return bmp;
    }

    public void setBmp(HashMap<Integer, List<Bitmap>> bmp) {
        this.bmp = bmp;
    }

    public HashMap<Integer, Integer> getHeight() {
        return height;
    }

    public void setHeight(HashMap<Integer, Integer> height) {
        this.height = height;
    }

    public HashMap<Integer, Integer> getWidth() {
        return width;
    }

    public void setWidth(HashMap<Integer, Integer> width) {
        this.width = width;
    }

    @Override
    public int getItemCount() {
        return recyclerData.size();
    }

    class viewHolder extends RecyclerView.ViewHolder {

        private ListView listView;

        viewHolder(View itemView) {
            super(itemView);
            listView = itemView.findViewById(R.id.listview);
        }
    }
}

Why you have to draw each item to create a screenshot ?

Case 1 : Your RecyclerView is static (show all item, scroll with parent - NestedScrollView ), recyclerView.setNestedScrollingEnabled(false);
If you are implementing this case, you don't need to draw each item, just draw root view:

public static Bitmap takeScreenShot(View view) {
                    Bitmap b = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
                    Canvas c = new Canvas(b);
                    view.draw(c);
                    return b;
                }

Case 2 : Your RecyclerView still enable recycle-technique, if we use your solution when the list has many items (100 items for example), the screenshot will look very different with actual view of user, it's also very tall and ugly bitmap .

I checked out your code, it works but it doesn't make sense to me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM