Я не могу заставить детей моего TableLayout
быть напечатанным на моем Canvas
объекте, который должен использоваться для создания PDF-файла с использованием PdfDocument
нативного для Android.
Единственное, что отображается в документе PDF, - это моя линейная диаграмма и раздувная разметка без видов, которые добавляются программно.
Вот следующая функция, которая предположительно генерирует указанный PDF:
private void generatePDF() throws IOException {
SAIHelper.createAndShowToast(getActivity(), "Generating PDF, please wait...");
PdfDocument pdfDocument = new PdfDocument();
PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(mLineChart.getWidth(), mLineChart.getHeight() + 842, 1).create();
PdfDocument.Page page = pdfDocument.startPage(pageInfo);
System.out.println("CHART WIDTH: " + mLineChart.getWidth());
System.out.println("CHART HEIGHT: " + mLineChart.getHeight());
LayoutInflater layoutInflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
TableLayout tableLayout = (TableLayout) layoutInflater.inflate(R.layout.table_layout, null);
tableLayout.measure(mLineChart.getWidth(), mLineChart.getHeight());
tableLayout.layout(0, 0, mLineChart.getWidth(), mLineChart.getWidth());
Canvas canvas = page.getCanvas();
canvas.save();
mLineChart.draw(canvas);
canvas.restore();
canvas.translate(0, mLineChart.getHeight());
int totalScore = 0;
int sad_lonely_unhappy = 0;
int happy = 0;
int disturbed_no_focus = 0;
int feeling_of_isolation = 0;
int sleep_problems = 0;
int hopeless = 0;
int fatigued_stressed = 0;
int pessimism = 0;
int uneasy_unstable = 0;
int moody = 0;
int emotional = 0;
int eating_problems = 0;
int low_self_esteem = 0;
int suicidal = 0;
int anxious = 0;
int pretending_to_be_happy = 0;
int have_no_emotional_support = 0;
int days = 0;
for (Entry entry : mEntries) {
JsonObject jsonObject = (JsonObject) entry.getData();
days++;
for (Map.Entry<String, JsonElement> entry1 : jsonObject.entrySet()) {
for (Map.Entry<String, JsonElement> entry2 : entry1.getValue().getAsJsonObject().entrySet()) {
switch (entry1.getKey()) {
case "sad_lonely_unhappy":
sad_lonely_unhappy += entry2.getValue().getAsInt();
break;
case "happy":
happy += entry2.getValue().getAsInt();
break;
case "disturbed_no_focus":
disturbed_no_focus += entry2.getValue().getAsInt();
break;
case "feeling_of_isolation":
feeling_of_isolation += entry2.getValue().getAsInt();
break;
case "sleep_problems":
sleep_problems += entry2.getValue().getAsInt();
break;
case "hopeless":
hopeless += entry2.getValue().getAsInt();
break;
case "fatigued_stressed":
fatigued_stressed += entry2.getValue().getAsInt();
break;
case "pessimism":
pessimism += entry2.getValue().getAsInt();
break;
case "uneasy_unstable":
uneasy_unstable += entry2.getValue().getAsInt();
break;
case "moody":
moody += entry2.getValue().getAsInt();
break;
case "emotional":
emotional += entry2.getValue().getAsInt();
break;
case "eating_problems":
eating_problems += entry2.getValue().getAsInt();
break;
case "low_self_esteem":
low_self_esteem += entry2.getValue().getAsInt();
break;
case "suicidal":
suicidal += entry2.getValue().getAsInt();
break;
case "anxious":
anxious += entry2.getValue().getAsInt();
break;
case "pretending_to_be_happy":
pretending_to_be_happy += entry2.getValue().getAsInt();
break;
case "have_no_emotional_support":
have_no_emotional_support += entry2.getValue().getAsInt();
break;
}
totalScore += entry2.getValue().getAsInt();
}
}
}
String[] array = {"sad_lonely_unhappy",
"happy",
"disturbed_no_focus",
"feeling_of_isolation",
"sleep_problems",
"hopeless",
"fatigued_stressed",
"pessimism",
"uneasy_unstable",
"moody",
"emotional",
"eating_problems",
"low_self_esteem",
"suicidal",
"anxious",
"pretending_to_be_happy",
"have_no_emotional_support"};
for (int i = 0; i < array.length; i++) {
TableRow tableRow = (TableRow) layoutInflater.inflate(R.layout.row_layout, tableLayout, false);
tableRow.measure(mLineChart.getWidth(), mLineChart.getHeight());
tableRow.layout(0, 0, mLineChart.getWidth(), mLineChart.getWidth());
// tableRow.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
TextView percentage = new TextView(getContext());
percentage.setText(array[i].replace('_', ' ').toUpperCase());
percentage.setTextSize(TypedValue.COMPLEX_UNIT_SP,8);
percentage.setTypeface(Typeface.create("avenir", Typeface.NORMAL));
percentage.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
percentage.setTextColor(Color.parseColor("#414953"));
// percentage.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
TextView category = new TextView(getContext());
category.setText(array[i].replace('_', ' ').toUpperCase());
category.setTextSize(TypedValue.COMPLEX_UNIT_SP,8);
category.setTypeface(Typeface.create("avenir", Typeface.NORMAL));
category.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
category.setTextColor(Color.parseColor("#414953"));
category.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
TextView avg = new TextView(getContext());
avg.setText(array[i].replace('_', ' ').toUpperCase());
avg.setTextSize(TypedValue.COMPLEX_UNIT_SP,8);
avg.setTypeface(Typeface.create("avenir", Typeface.NORMAL));
avg.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
avg.setTextColor(Color.parseColor("#414953"));
// avg.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
int theInt = 0;
switch (array[i]) {
case "sad_lonely_unhappy":
theInt = sad_lonely_unhappy;
percentage.setText(((sad_lonely_unhappy / totalScore) * 100) + "%");
break;
case "happy":
theInt = happy;
percentage.setText(((happy / totalScore) * 100) + "%");
break;
case "disturbed_no_focus":
theInt = disturbed_no_focus;
percentage.setText(((disturbed_no_focus / totalScore) * 100) + "%");
break;
case "feeling_of_isolation":
theInt = feeling_of_isolation;
percentage.setText(((feeling_of_isolation / totalScore) * 100) + "%");
break;
case "sleep_problems":
theInt = sleep_problems;
percentage.setText(((sleep_problems / totalScore) * 100) + "%");
break;
case "hopeless":
theInt = hopeless;
percentage.setText(((hopeless / totalScore) * 100) + "%");
break;
case "fatigued_stressed":
percentage.setText(((fatigued_stressed / totalScore) * 100) + "%");
theInt = fatigued_stressed;
break;
case "pessimism":
percentage.setText(((pessimism / totalScore) * 100) + "%");
theInt = pessimism;
break;
case "uneasy_unstable":
percentage.setText(((uneasy_unstable / totalScore) * 100) + "%");
theInt = uneasy_unstable;
break;
case "moody":
percentage.setText(((moody / totalScore) * 100) + "%");
theInt = moody;
break;
case "emotional":
percentage.setText(((emotional / totalScore) * 100) + "%");
theInt = emotional;
break;
case "eating_problems":
percentage.setText(((eating_problems / totalScore) * 100) + "%");
theInt = eating_problems;
break;
case "low_self_esteem":
percentage.setText(((low_self_esteem / totalScore) * 100) + "%");
theInt = low_self_esteem;
break;
case "suicidal":
percentage.setText(((suicidal / totalScore) * 100) + "%");
theInt = suicidal;
break;
case "anxious":
percentage.setText(((anxious / totalScore) * 100) + "%");
theInt = anxious;
break;
case "pretending_to_be_happy":
percentage.setText(((pretending_to_be_happy / totalScore) * 100) + "%");
theInt = pretending_to_be_happy;
break;
case "have_no_emotional_support":
percentage.setText(((have_no_emotional_support / totalScore) * 100) + "%");
theInt = have_no_emotional_support;
break;
}
avg.setText(theInt / days + "");
tableRow.addView(percentage);
tableRow.addView(category);
tableRow.addView(avg);
tableLayout.addView(tableRow);
System.out.println("TABLE LAYOUT CHILDREN: " + tableLayout.getChildCount());
}
//
// tableLayout.invalidate();
// tableLayout.refreshDrawableState();
tableLayout.draw(canvas);
pdfDocument.finishPage(page);
Calendar calendar = Calendar.getInstance();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-dd-MM_HH_mm_ss");
String theFileName = "SAI_Report_gen_" + simpleDateFormat.format(calendar.getTime()) + ".pdf";
String pathName = Environment.getExternalStorageDirectory() + "/SAIChatbot";
File file = new File(pathName);
if (!file.exists())
file.mkdir();
pdfDocument.writeTo(new FileOutputStream(new File(pathName, theFileName)));
SAIHelper.createAndShowToast(getActivity(), "PDF Generated");
}
А для макета xmls:
table_layout.xml
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stretchColumns="*"
android:padding="10dp"
android:id="@+id/tableLayoutMain">
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="10sp"
android:fontFamily="@font/avenir_bold"
android:text="PERCENTAGE"
android:textAlignment="center"
android:textColor="@color/darkGrey" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="10sp"
android:fontFamily="@font/avenir_bold"
android:text="CATEGORY"
android:textAlignment="center"
android:textColor="@color/darkGrey" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="10sp"
android:fontFamily="@font/avenir_bold"
android:text="AVG SCORE"
android:textAlignment="center"
android:textColor="@color/darkGrey" />
</TableRow>
</TableLayout>
row_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<TableRow
android:id="@+id/tableRowMain"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android">
</TableRow>
Ниже приведен скриншот созданного файла PDF:
PDF
Как вы можете видеть, только завышенные TableLayout
до добавления дочерних представлений отрисовываются в PDF.
Но когда я экспериментировал с отображением TableLayout
для проверки правильности структуры, он успешно отображался.
Я пытался поставить TableLayout.LayoutParams()
для TableLayout
и TableRow.LayoutParams()
для TableRow
, но безрезультатно, это не работает.
Я также попытался поэкспериментировать с методами requestLayout()
и invalidate()
, чтобы выяснить, не связана ли проблема с обновлением TableLayout после динамического добавления дочерних TableRows, тем не менее, не повезло.
Я потратил несколько дней на то, как реализовать эту мою функцию, и я был бы признателен, если бы вы помогли мне с моим текущим затруднением.