Sunday, 1 February 2015

Android Dynamic RelativeLayout with vertical rows



I'm trying to build a dynamic layout that will be generated into a PDF via the PDFDocument class. I have the PDF generation working as well as the majority of my layout. However, I am running into a road block when it comes to dynamically adding a RelativeLayout to an existing RelativeLayout.


The idea is that I'm trying to build a table with a dynamic number of rows. Each row consists of a RelativeLayout along with a LinearLayout that contains five TextViews. The display of these views all work as expected except for the vertical positioning of each row. The rows are all rendered one on top of the other instead of vertically.


I am using the RelativeLayout.BELOW setting to tell the layout to position the new row below the last. I am also using dynamic ViewIDs that are basically just int 1 - 10. I do not have any other views with the same IDs.


Anyways, below is my layout code as well as my Java logic. Can someone please help shed some light on what I'm doing here?


pdf_report.xml - This is the layout for the entire report. Some of the markup has been omitted to prevent confusion, but the hierarchy of views is the same. Please keep in mind the level of RelativeLayouts is due to a complex(ish) layout I'm trying to accomplish, but I don't want to bog anyone down with forcing them to look for what I'm having an issue with.



<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://ift.tt/nIICcg"
android:layout_width="1654px"
android:layout_height="2339px"
android:id="@+id/ReportPDFView"
android:background="@color/activityBackground">

<RelativeLayout
android:layout_width="1454px"
android:layout_height="wrap_content"
android:layout_below="@id/ReportPDFLogoImageView"
android:layout_marginTop="100px"
android:layout_marginLeft="100px">

<!-- CashFlow Table -->
<RelativeLayout
android:id="@+id/ReportPDFCashFlowTable"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/ReportPDFBreakPenaltyLayout"
android:layout_marginTop="60px">

<!-- CashFlow Table Rows -->
<RelativeLayout
android:id="@+id/ReportPDFCashFlowTableRowsLayout"
android:layout_width="match_parent"
android:layout_height="500px"
android:layout_below="@id/ReportPDFCashFlowTableHeaderBorder"
android:layout_marginTop="25px">

</RelativeLayout>

</RelativeLayout>

</RelativeLayout>

</RelativeLayout>


The ReportPDFCashFlowTableRowsLayout layout is the parent layout that I will be adding my rows to.


pdf_report_cashflow_row.xml - This is just my very simple row layout file.



<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://ift.tt/nIICcg"
android:orientation="vertical"
android:layout_width="1454px"
android:layout_height="25px"
android:layout_marginTop="25px">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

... TEXT VIEWS HERE ...

</LinearLayout>

</RelativeLayout>


Java Function that creates my layout rows.



private View getReportLayout()
{
pdfView = null;

try
{
Size pageSize = Globals.GetPageSize();
Size rowSize = Globals.GetCashFlowRowSize();

LayoutInflater layoutInflater = LayoutInflater.from(_context);
pdfView = layoutInflater.inflate(R.layout.pdf_report, null);
pdfView.measure(pageSize.Width, pageSize.Height);
pdfView.layout(0, 0, pageSize.Width, pageSize.Height);

// Build CashFlow table
Integer height = 0;

RelativeLayout rowView = null;
RelativeLayout.LayoutParams params = null;
RelativeLayout tableRowLayout = (RelativeLayout)pdfView.findViewById(R.id.ReportPDFCashFlowTableRowsLayout);

Integer lastViewID = null;

for (Integer year = 1; year <= years; year++)
{
// set params
params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, Globals.GetCashFlowRowSize().Height);
params.setMargins(0, 25, 0, 0);

if (lastViewID != null) {
params.addRule(RelativeLayout.BELOW, lastViewID);
}

// get row view
rowView = (RelativeLayout)layoutInflater.inflate(R.layout.pdf_report_cashflow_row, null);
rowView.setId(year);
rowView.measure(rowSize.Width, rowSize.Height);
rowView.layout(0, 0, rowSize.Width, rowSize.Height);
tableRowLayout.addView(rowView, params);

// margin and height
height += rowSize.Height;
lastViewID = year;
}

// Set height
params = (RelativeLayout.LayoutParams)tableRowLayout.getLayoutParams();
params.height = height;
tableRowLayout.setLayoutParams(params);
}
catch (Exception ex)
{
logger.e("[AppReportOptionsFragment][getReportLayout] Exception: " + ex.toString());
}

return pdfView;
}


Finally, here is my PDF generation logic that I pass the pdfView object into.



@TargetApi(Build.VERSION_CODES.KITKAT)
public static File GeneratePDF(Context context, View content, int pagewidth, int pageHeight, String fileName)
{
// create a new document
PdfDocument document = new PdfDocument();

// crate a page description
PageInfo pageInfo = new PageInfo.Builder(pagewidth, pageHeight, 1).create();

// start a page
Page page = document.startPage(pageInfo);

// draw something on the page
content.draw(page.getCanvas());

// finish the page
document.finishPage(page);

// write the document content
File file = null;
FileOutputStream stream = null;

try
{
file = File.createTempFile(fileName.replace(" ", "_"), ".pdf");

stream = new FileOutputStream(file);
document.writeTo(stream);
stream.close();
}
catch (Exception e)
{
logger.e("[PDFBusiness][GeneratePDF] - Exception: " + e.toString());
}

// close the document
document.close();

return file;
}


Thanks!


No comments:

Post a Comment