1

i am wondering that how i can save the whole view(horizontally and vertically scrollable) as image or pdf? is there a way of doing same...? my layout(below) contains a table which i wanna save ! i have searched google but i was not able to figure out the way for doing that

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".DetailedAttendance"
    android:background="@drawable/animation_back_grad1"
    android:padding="5dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="50dp">

    <ScrollView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scrollbars="vertical" >

        <HorizontalScrollView
            android:layout_width="match_parent"
            android:layout_height="fill_parent"
            android:fadeScrollbars="false">

            <TableLayout
                android:id="@+id/detailedAttendanceTable"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
        </HorizontalScrollView>
    </ScrollView>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true">

        <Button
            android:id="@+id/exitApp1"
            android:layout_weight=".5"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:background="@drawable/reg_button_back"
            android:text="Exit"
            android:textColor="#F3677C" />
        <Button
            android:id="@+id/back"
            android:layout_weight=".5"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:background="@drawable/reg_button_back"
            android:text="Back"
            android:textColor="#F3677C" />


    </LinearLayout>

</RelativeLayout>

any little help will be appereciated ! thanks :)

1 Answers1

0

I am not sure if this is what you need but, here you have a way to save a layout as a pdf document. I haven't included all the permissions part you need to ask to save the file in external files, this just focuses on the pdf generation.

The idea is to create a layout, inflate it, and set the data as if it were an activitie's view. Then instead of drawing the layout to the screen you draw it to a Canvas that is part of the PdfDocument.

R.layout.pdf_resultado is the layout (xml) to use for the pdf.

private static final int PAGE_WIDTH = 612;
private static final int PAGE_HEIGHT = 792;

public void createPdf(File pdfFile, SomeDataSource dataSourceObject){

    LayoutInflater inflater = (LayoutInflater)
            context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View content = inflater.inflate(R.layout.pdf_resultado, null);

    // Get references to views on the layout
    tvResultRef = content.findViewById(R.id.tvResultRef);
    ...

    // Set the data for the views;
    tvResultRef.setText(dataSourceObject.getTheDataForResultRefView());
    ...

    // Make the pdf document
    PdfDocument pdfDocument = new PdfDocument();
    PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo
            .Builder(PAGE_WIDTH,PAGE_HEIGHT,1).create();
    PdfDocument.Page page = pdfDocument.startPage(pageInfo);

    Canvas canvas = page.getCanvas();

    // I came up with the next lines to scale the view to fit the page.
    // Perhaps there is a better way of doing it but at the time I wasn't able to find much information
    // on this.

    int measureWidth = View.MeasureSpec.makeMeasureSpec(page.getCanvas().getWidth(), View.MeasureSpec.UNSPECIFIED);
    int measuredHeight = View.MeasureSpec.makeMeasureSpec(page.getCanvas().getHeight(), View.MeasureSpec.UNSPECIFIED);

    content.measure(measureWidth, measuredHeight);
    content.layout(0, 0, page.getCanvas().getWidth(), page.getCanvas().getHeight());

    //String msg = String.format("canvas w %d canvas h %d content w %d content h %d",page.getCanvas().getWidth(), page.getCanvas().getHeight(),
    //        content.getMeasuredWidth(), content.getMeasuredHeight());
    //Log.d(TAG,msg);

    float xRatio = ((float) canvas.getWidth()) /( (float) content.getMeasuredWidth());
    float yRatio = ((float) canvas.getHeight()) /( (float) content.getMeasuredHeight());

    float scale;
    if(xRatio < yRatio){
        scale = xRatio;
    }else{
        scale = yRatio;
    }

    canvas.scale(scale,    scale);
    content.draw(canvas);

    pdfDocument.finishPage(page);

    try {
        pdfDocument.writeTo(new FileOutputStream(pdfFile));
        Toast.makeText(context, context.getString(R.string.pdfSavedInDocs), Toast.LENGTH_LONG).show();
    } catch (IOException e) {
        e.printStackTrace();
        Toast.makeText(context, context.getString(R.string.errorGuardandoPDF),
                Toast.LENGTH_LONG).show();
    }

    // close the document
    pdfDocument.close();
}

EDIT I

The someDataSource object is just an object carrying the information to populate the views.

For example:

public class SomeDataSource{
    private String name;
    private String lastName;
    private String resultRef;

    // Getters & Setters
}

To setup the layout with data you instantiate an object of this class, fill it with the info to display, and call the createPdf() method with it.

SomeDataSource dataSourceObject= new SomeDataSource();
dataSourceObject.setName("John"); 
dataSourceObject.setLastName("Doe");
dataSourceObject.setResultRef("ResultReference: X123-1");

createPdf(new File("John_Doe_Result.pdf", dataSourceObject); 

The tvResultRef object is a view of the layout, like a TextView.

Like in an Activity's onCreate() method first you get a references to the view in the layout:

tvResultRef = content.findViewById(R.id.tvResultRef);

Then you set a value for it to show:

tvResultRef.setText(dataSourceObject.getResultRef());

And do the same with the other views in the layout.

Juan
  • 5,525
  • 2
  • 15
  • 26