繁体   English   中英

拍摄完整长度的RecyclerView屏幕快照..每个项目都有一个列表

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

我正在使用具有动态大小列表的recyclerView ...并且当我使用此方法拍摄每个recyclerView项目的屏幕截图时。它获取屏幕截图,但每个项目仅包含一个列表项目。即使列表项目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是:- 在此处输入图片说明

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

对于每个recycler item屏幕快照,仅显示1项目。

面对同样的问题,并通过使用这段代码解决了这个问题。

首先,要求您的视图计算其测量值,然后要求视图提供MeasuredHeight并完成所有操作。

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

这样可以解决问题,

我创建了一个位图bmOverlay,以在该位图上绘制两个位图。 另外,我还使用了另一个For循环来为listview Items创建位图。

这是我对您的代码所做的更改:

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

这是我的RecycleView适配器,

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

为什么必须绘制每个项目才能创建屏幕截图?

情况1 :您的RecyclerView是静态的(显示所有项目,使用父滚动-NestedScrollView ), recyclerView.setNestedScrollingEnabled(false);
如果要实现这种情况,则无需绘制每个项目,只需绘制根视图即可:

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

情况2 :您的RecyclerView仍启用回收技术,如果我们在列表中有很多项目(例如100个项目)时使用您的解决方案, 则屏幕快照与用户的实际视图截然不同,它的位图也非常丑陋

我签出了您的代码,它可以正常工作,但对我来说却没有意义。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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