【问题标题】:create PDF of RecyclerView in FULL length以全长创建 RecyclerView 的 PDF
【发布时间】:2016-11-11 17:53:18
【问题描述】:

我想创建活动“整页”的 PDF。该视图包含一个包含许多项目的 RecyclerView。

我可以获取 Recyclerview 的完整尺寸,但文件仅绘制当前视图。这是我的代码:

    public void tela (){ // create a new document
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)

    {
        PdfDocument document = new PdfDocument();

        getScreenshotFromRecyclerView(mRecyclerView);
        content = mRecyclerView;
        content.setBackgroundColor(Color.parseColor("#303030"));


        PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(wil,
                height, 1).create();

    // create a new page from the PageInfo
        PdfDocument.Page page = document.startPage(pageInfo);

    // repaint the user's text into the page
        content.draw(page.getCanvas());

    // do final processing of the page
        document.finishPage(page);

    // saving pdf document to sdcard
        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy - HH-mm-ss",Locale.getDefault());
        String pdfName = "Revisões_"
                + sdf.format(Calendar.getInstance().getTime()) + ".pdf";

    // all created files will be saved at path /sdcard/PDFDemo_AndroidSRC/
        File outputFile = new File(Environment.getExternalStorageDirectory().getPath(), pdfName);

        try {
            outputFile.createNewFile();
            OutputStream out = new FileOutputStream(outputFile);
            document.writeTo(out);
            document.close();
            out.close();
            Toast.makeText(this,"PDF gerado com sucesso",Toast.LENGTH_SHORT).show();
            Log.i("Gerou", "pdf");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

// 获取限制

    public void getScreenshotFromRecyclerView(RecyclerView view) {
    RecyclerView.Adapter adapter = view.getAdapter();
    if (adapter != null) {
        int size = adapter.getItemCount();

        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());
            height += holder.itemView.getMeasuredHeight();
        }
        wil=view.getMeasuredWidth();


    }
}

结果是这样的:

我可以使用我的 Recyclerview 的所有值创建 pdf 吗?

谢谢。

【问题讨论】:

    标签: android android-studio pdf-generation android-recyclerview


    【解决方案1】:

    我实现了一个帮助类来处理保存到 PDF 的图像。在方法 saveImageToPDF() 我通过:

    • 一个 TabLayout,位于我的 recyclerView 上方
    • recyclerView 的 Bitmap
    • 上下文

    为了得到recyclerView Bitmap,我使用了这个Take a screenshot of RecyclerView in FULL length

    public class PDFHelper {
    
        private File mFolder;
        private File mFile;
        private Context mContext;
    
        public PDFHelper(File folder, Context context) {
    
            this.mContext = context;
            this.mFolder = folder;
    
            if(!mFolder.exists())
                mFolder.mkdirs();
        }
    
        public void saveImageToPDF(View title, Bitmap bitmap, String filename) {
    
            mFile = new File(mFolder, filename + ".pdf");
            if (!mFile.exists()) {
                int height = title.getHeight() + bitmap.getHeight();
                PdfDocument document = new PdfDocument();
                PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(bitmap.getWidth(), height, 1).create();
                PdfDocument.Page page = document.startPage(pageInfo);
                Canvas canvas = page.getCanvas();
                title.draw(canvas);
    
                canvas.drawBitmap(bitmap, null, new Rect(0, title.getHeight(), bitmap.getWidth(),bitmap.getHeight()), null);
    
                document.finishPage(page);
    
                try {
                    mFile.createNewFile();
                    OutputStream out = new FileOutputStream(mFile);
                    document.writeTo(out);
                    document.close();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
        }
    }
    

    【讨论】:

      【解决方案2】:

      我找到了一种更简单的方法。我不确定我的代码是否干净或者这是正确的方法。我有一个可变大小的回收站视图。我想以 pdf 格式打印整个回收站视图。我也使用 IText Pdf 仅供参考。

      我做过的事情。 下面是回收站视图中单个项目的 XML 文件。请注意,当我使用卡片视图时,我已经为卡片视图提供了一个 ID(您可以使用任何您想要的作为根、LinearLayout 或 RelativeLayout 等)android:id="@+id/preview_order_list_card_root"

          <?xml version="1.0" encoding="utf-8"?>
      <android.support.v7.widget.CardView
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/preview_order_list_card_root"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_marginTop="5dp"
          android:layout_marginBottom="5dp">
      
          <LinearLayout
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:orientation="vertical">
      
              <LinearLayout
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:layout_margin="5dp">
      
                  <LinearLayout
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      android:orientation="vertical">
      
                      <ImageView
                          android:layout_width="50dp"
                          android:layout_height="50dp"
                          android:layout_gravity="center_horizontal"
                          android:src="@drawable/car"/>
      
                      <TextView
                          android:layout_width="1dp"
                          android:layout_height="wrap_content"
                          android:layout_gravity="center"
                          android:background="@android:color/darker_gray"
                          android:text="12"/>
      
                      <TextView
                          android:id="@+id/preview_car_name"
                          android:layout_width="90dp"
                          android:layout_height="wrap_content"
                          android:layout_gravity="center"
                          android:layout_marginTop="7dp"
                          android:gravity="center"
                          android:textSize="20sp"
                          android:textStyle="bold"/>
      
                      <TextView
                          android:id="@+id/preview_car_model"
                          android:layout_width="90dp"
                          android:layout_height="wrap_content"
                          android:layout_gravity="center"
                          android:gravity="center"/>
      
                  </LinearLayout>
      
                  <TextView
                      android:layout_width="1dp"
                      android:layout_height="match_parent"
                      android:layout_marginLeft="5dp"
                      android:layout_marginRight="5dp"
                      android:background="@android:color/darker_gray"/>
      
                  <LinearLayout
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      android:orientation="vertical">
      
                      <TextView
                          android:id="@+id/preview_part_name"
                          android:layout_width="100dp"
                          android:layout_height="wrap_content"
                          android:layout_gravity="center"
                          android:layout_marginTop="7dp"
                          android:gravity="center"
                          android:textSize="20sp"
                          android:textStyle="bold"/>
      
                      <TextView
                          android:id="@+id/preview_part_model"
                          android:layout_width="100dp"
                          android:layout_height="wrap_content"
                          android:layout_gravity="center"
                          android:layout_marginBottom="7dp"
                          android:gravity="center"/>
      
                      <TextView
                          android:layout_width="1dp"
                          android:layout_height="wrap_content"
                          android:layout_gravity="center"
                          android:background="@android:color/darker_gray"
                          android:text="12"/>
      
                      <ImageView
                          android:layout_width="50dp"
                          android:layout_height="50dp"
                          android:layout_gravity="center_horizontal"
                          android:src="@drawable/car_part"/>
      
                  </LinearLayout>
      
                  <TextView
                      android:layout_width="1dp"
                      android:layout_height="match_parent"
                      android:layout_marginLeft="5dp"
                      android:background="@android:color/darker_gray"/>
      
                  <LinearLayout
                      android:layout_width="70dp"
                      android:layout_height="wrap_content"
                      android:layout_gravity="center"
                      android:layout_marginLeft="5dp"
                      android:orientation="vertical">
      
                      <TextView
                          android:id="@+id/preview_quantity"
                          android:layout_width="wrap_content"
                          android:layout_height="wrap_content"
                          android:textColor="@android:color/holo_green_light"
                          android:gravity="center"
                          android:textSize="25sp"
                          android:layout_gravity="center"/>
      
                      <TextView
                          android:id="@+id/preview_quantity_bucket"
                          android:layout_width="wrap_content"
                          android:layout_height="wrap_content"
                          android:layout_gravity="center"
                          android:layout_marginTop="15dp"
                          android:gravity="center"/>
      
                  </LinearLayout>
      
              </LinearLayout>
      
              <LinearLayout
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:layout_gravity="bottom"
                  android:layout_margin="15dp"
                  android:orientation="vertical">
      
                  <TextView
                      android:id="@+id/preview_extra_info"
                      android:layout_width="match_parent"
                      android:layout_height="wrap_content"
                      android:layout_centerVertical="true"
                      android:gravity="center"/>
      
                  <LinearLayout
                      android:layout_width="match_parent"
                      android:layout_height="wrap_content"
                      android:orientation="horizontal"
                      android:layout_marginTop="15dp">
      
                      <TextView
                          android:id="@+id/preview_ordered_from"
                          android:layout_width="100dp"
                          android:layout_height="wrap_content"
                          android:textColor="@android:color/holo_red_light"/>
      
                      <TextView
                          android:id="@+id/preview_list_price"
                          android:layout_width="100dp"
                          android:layout_height="wrap_content"
                          android:gravity="center"/>
      
                      <TextView
                          android:id="@+id/preview_list_less"
                          android:layout_width="80dp"
                          android:layout_height="wrap_content"
                          android:gravity="right"/>
      
                  </LinearLayout>
      
              </LinearLayout>
      
          </LinearLayout>
      
      </android.support.v7.widget.CardView>
      

      现在在您的适配器中创建一个带有 getter 和 setter 的数组列表,当它调用 onBindViewHolder 时将保存卡片视图对象,如下所示。

      private static ArrayList<CardView> cardViewArrayList = new ArrayList<>();
      
      @Override
          public void onBindViewHolder(final PreviewOrderAdapter.MyViewHolder holder, int position)
          {
              OrderItemDetailsModel orderItemDetailsModel = namesArrList.get(position);
              holder.orderedFrom.setText(orderItemDetailsModel.getOrderedFrom());
              holder.listPrice.setText(orderItemDetailsModel.getListPrice());
              holder.listLess.setText(orderItemDetailsModel.getListLess());
      
              // ADDING THE CARD VIEW OBJECT IN THE ARRAYLIST
              addCardView(holder.cardView);
          }
      
          @Override
          public int getItemCount()
          {
              return namesArrList.size();
          }
      
          private static void addCardView(CardView cardView)
          {
              cardViewArrayList.add(cardView);
          }
      
          public static ArrayList<CardView> getCardViewList()
          {
              return cardViewArrayList;
          }
      

      现在最后,在打印回收站视图时执行此操作。

      //Getting the card view array list from the adapter above
      ArrayList<CardView> cardViewArrayList = adapter.getCardViewList();
                      for (int i = 0; i < cardViewArrayList.size(); i++)
                      {
                          // Iterate till the last of the array list and add each view individually to the document.
                          addContent(document, cardViewArrayList.get(i));
                      }
      
      //Adding the content to the document
      private void addContent(Document document, View view)
                  throws DocumentException
          {
              try
              {
                  view.buildDrawingCache();
      
                  Bitmap bmp = view.getDrawingCache();
      
                  ByteArrayOutputStream stream = new ByteArrayOutputStream();
                  bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
                  Image image = Image.getInstance(stream.toByteArray());
                  image.scalePercent(70);
                  image.setAlignment(Image.MIDDLE);
                  document.add(image);
              }
              catch (Exception ex)
              {
                  Log.e("TAG-ORDER PRINT ERROR", ex.getMessage());
              }
          }
      

      通过这种方式,我们不必担心由于回收器视图的大尺寸而导致的内存泄漏,因为我们将每个视图单独添加到文档中。

      【讨论】:

      • 我如何设法解决您的想法,这是一次成功的尝试,但有一个问题。只有来自 recyclerview 的可见单元格显示在保存的 PDF 文件中。你遇到过这样的问题吗?
      猜你喜欢
      • 2017-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多