TableLayout детей не рисуется на PdfDocument.Page.Canvas - PullRequest
0 голосов
/ 05 марта 2019

Я не могу заставить детей моего 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, тем не менее, не повезло.

Я потратил несколько дней на то, как реализовать эту мою функцию, и я был бы признателен, если бы вы помогли мне с моим текущим затруднением.

...