Добавление представлений программно в LinearLayout, но они не отображаются - PullRequest
1 голос
/ 11 февраля 2020

Я пытаюсь заполнить LinearLayout внутри simple_pdf_example.xml 10 printed_order_element2.xml, чтобы я мог сгенерировать PDF с ListView (что на самом деле LinearLayout).

Проблема в том, что когда я делаю linearLayoutView.addView(v) 10 раз, я не вижу v внутри LinearLayout. Я просто вижу исходный элемент, который я добавил в xml, чтобы увидеть, рендерился ли LinearLayout.

SimplePDFSaver. java:

package com.mypackage.example;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;

import android.content.Intent;
import android.graphics.pdf.PdfDocument;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;

import java.io.File;
import java.io.FileOutputStream;


public class SimplePDFSaver extends AppCompatActivity {
    private static final String TAG = "SimplePDFSaver";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_simple_pdfsaver);
        generatePDF();
    }

    public void generatePDF() {
        LayoutInflater inflater = getLayoutInflater();
        View pdfLayout = inflater.inflate(R.layout.simple_pdf_example,
            findViewById(android.R.id.content),
            false);


        int sizeSpec = View.MeasureSpec.makeMeasureSpec(2480, View.MeasureSpec.EXACTLY);
        int sizeSpec2 = View.MeasureSpec.makeMeasureSpec(3508, View.MeasureSpec.EXACTLY);
        pdfLayout.measure(sizeSpec, sizeSpec2);

        int width = pdfLayout.getMeasuredWidth();
        int height = pdfLayout.getMeasuredHeight();
        pdfLayout.layout(0, 0, width, height);

        LinearLayout linearLayoutView = pdfLayout.findViewById(R.id.linearLayoutView);

        for (int i=0; i<10; i++) {
            View v = getLayoutInflater().inflate(R.layout.printed_order_element2, null);
            linearLayoutView.addView(v);
        }

        Runnable r = new Runnable() {
            @Override
            public void run() {

                PdfDocument document = new PdfDocument();
                PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(2480, 3508, 0).create();
                PdfDocument.Page page = document.startPage(pageInfo);

                pdfLayout.draw(page.getCanvas());
                document.finishPage(page);

                FileOutputStream outStream;
                File file = new File(getExternalFilesDir(null), "file.pdf");
                try {
                    outStream = new FileOutputStream(file);
                    document.writeTo(outStream);
                    document.close();
                    outStream.flush();
                    outStream.getFD().sync();
                    outStream.close();

                    Intent intent = new Intent(Intent.ACTION_VIEW);
                    Uri uri = FileProvider.getUriForFile(SimplePDFSaver.this, BuildConfig.APPLICATION_ID + ".provider", file);
                    intent.setDataAndType(uri, "application/pdf");
                    intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                    startActivity(intent);
                } catch (Exception e) {
                    e.printStackTrace();
                    Log.d(TAG, e.toString());
                }
            }
        };
        new Thread(r).start();
    }
}

simple_pdf_example. xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/linearLayoutView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:orientation="vertical"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView10">


        <TextView
            android:id="@+id/textView13"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Just to see if linearLayoutView rendered" />
    </LinearLayout>

    <TextView
        android:id="@+id/textView10"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="There should be a list of items below:"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

print_order_element2. xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textView6"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView" />
</LinearLayout>

Вот что я получаю:

enter image description here

Ответы [ 3 ]

1 голос
/ 13 февраля 2020

Я полагаю, что проблема заключается в этом разделе кода:

public void generatePDF() {
    LayoutInflater inflater = getLayoutInflater();
    View pdfLayout = inflater.inflate(R.layout.simple_pdf_example,
            findViewById(android.R.id.content),
            false);

Весь остальной код использует это раздутое pdfLayout представление:

LinearLayout linearLayoutView = pdfLayout.findViewById(R.id.linearLayoutView);

for (int i=0; i<10; i++) {
    View v = getLayoutInflater().inflate(R.layout.printed_order_element2, null);
    linearLayoutView.addView(v);
}
pdfLayout.draw(page.getCanvas());

Проблема в том, что ваше представление pdfLayout никогда не отображается на экране. Ваш setContentView() вызов в onCreate() раздувает другой макет, а надутый pdfLayout никогда не присоединяется ни к какому представлению!

Когда вы вызываете inflate(int, View, boolean) и передаете false в качестве третьего аргумента, вы говорят системе обрабатывать второй аргумент (View) как родительский только , чтобы проанализировать LayoutParams на root раздутого макета. Раздутый макет не добавляется к родителю! Вы должны вручную вызвать parent.addView() с раздутым видом.


Как это исправить? Трудно сказать точно, так как у меня есть несколько вопросов. Но, возможно, простое задание вопросов покажет ответ.

Странно видеть и вызов setContentView() и вызов inflate(), который передается в android.R.id.content как родитель , Не могли бы вы просто набрать setContentView(R.layout.simple_pdf_example) в своем onCreate() и вообще избежать второго inflate() вызова?

Если это так, то вы заменили бы все вызовы на pdfLayout.findViewById() на прямые findViewById() вызовы ( поскольку то, что раньше было pdfLayout, теперь является основным содержанием вашей деятельности.

1 голос
/ 11 февраля 2020

Ваш linearLayoutView находится в pdfLayout, но когда вы надуваете pdfLayout, вы не добавляете его к родителю. Пожалуйста, попробуйте так:

View pdfLayout = inflater.inflate(R.layout.simple_pdf_example, findViewById(android.R.id.content));
0 голосов
/ 13 февраля 2020

Просто добавьте

    pdfLayout.measure(sizeSpec, sizeSpec2);
    pdfLayout.layout(0, 0, width, height);

после того, как for l oop исправит все. Благодаря Бену П. { ссылка }

Проблема в том, что макет должен быть измерен мной или макет () должен быть выполнен. Не знаю точно, но это связано с этим. Я не знаю, нужны ли эти 2 строки, но вы можете попробовать использовать только одну и посмотреть, что работает

...