【问题标题】:How to render an android view to canvas WITHOUT rendering it first (i.e. without full layout)如何在不先渲染的情况下将 android 视图渲染到画布(即没有完整布局)
【发布时间】:2020-03-07 21:37:05
【问题描述】:

我正在尝试使用View.draw( Canvas canvas ) 在外部画布上绘制视图。为此,视图必须事先执行完整的布局。

但是,我调用View.draw( Canvas canvas ) 的原因是我可以从视图中生成一个 PdfDocument,同时利用现有的小部件而不是自定义绘制我的代码中的所有内容。换句话说,在内存中而不是在屏幕上调用视图(及其子视图)的完整布局......如果这有意义的话。

我希望创建一个具有固定高度和宽度的视图(不渲染它),然后将视图转储到 PdfDocument 页面的画布上。

这可以做到吗?如果可以,有什么诀窍?

如果没有,有没有更好的方法?

【问题讨论】:

  • IIRC,在View 上致电measure()layout()

标签: java android canvas


【解决方案1】:

与在屏幕上绘图相比,您需要像@CommonsWare 所说的那样设置布局参数、测量和布局。

在我的应用程序中,我绘制了一个视图以保存为 PNG 并进行打印,但您也可以在位图上将其保存为 PDF 文档。

请注意,这种技术似乎不适用于滚动的内容,因为您通常只能获得将在屏幕上显示的内容。

在我的例子中,我在滚动视图中有一个大的 TableLayout,所以我将 TableLayout 绘制到位图而不是滚动视图。

我生成名为 viewTableLayout 然后保存到 PNG 我执行以下操作(这很容易适应 pdf 文件)

我使用的代码的摘录(因为我使用相同的代码来实际绘制到屏幕上,一旦布局完成,我通过 Id 找到我想要保存到 PNG 的内容)


int tableLayoutId = 1;
float scaleFactor = 0.5f;

TableLayout tableLayout = new TableLayout(DetailedScoresActivity.this);
        tableLayout.setId(tableLayoutId);

// More code to fill out the TableLayout

// .....

// Then Need to full draw this view as it has not been shown in the gui
            tableLayout.setLayoutParams(new TableLayout.LayoutParams(TabLayout.LayoutParams.WRAP_CONTENT,
                    TabLayout.LayoutParams.WRAP_CONTENT));
            tableLayout.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                    View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
            tableLayout.layout(0, 0, tableLayout.getMeasuredWidth(), tableLayout.getMeasuredHeight());

            Canvas bitmapCanvas = new Canvas();
            Bitmap bitmap = Bitmap.createBitmap(Math.round(tableLayout.getWidth() * scaleFactor), Math.round(tableLayout.getHeight() * scaleFactor), Bitmap.Config.ARGB_8888);

            bitmapCanvas.setBitmap(bitmap);
            bitmapCanvas.scale(scaleFactor, scaleFactor);
            tableLayout.draw(bitmapCanvas);

【讨论】:

  • 太棒了,伙计。由于我的自定义视图没有父视图并且没有显示,我让您的代码 sn-p(与我的代码混合)通过指定精确尺寸和使用 View.MeasureSpec.EXACTLY 与 makeMeasureSpec ...
猜你喜欢
  • 1970-01-01
  • 2018-05-14
  • 2014-01-17
  • 1970-01-01
  • 1970-01-01
  • 2014-12-03
  • 1970-01-01
  • 2021-09-20
相关资源
最近更新 更多