1

I have a view whose contents exceed the bounds of the display, such as a scrollable content. There are already posts on how to create a bitmap of a view but these are all limited to creating a bitmap that will only show that portion of the view that is visible on the screen. I need to include that part that is not shown.

I thought that the view's drawing cache might be the way to go but am not sure how to do this as the code samples I have found are limited to the screen size.

IMPORTANT: My app is hardware acceleration enabled, so any attempt to use a software canvas will fail as all views are bound to a hardware canvas.

Johann
  • 27,536
  • 39
  • 165
  • 279

1 Answers1

0

The answer is you can draw direct to a bitmap, see how to do this at https://stackoverflow.com/a/60582865/2373819

The key is to measure it with View.MeasureSpec.UNSPECIFIED which will draw it with without any screen size limitations (all child elements will be allowed to be sized to their contents, if they specify this)

Note this can use a large amount of memory if the view is big (the scale factor can be used to reduce the amount of memory used at the expense of quality.)

Andrew
  • 8,198
  • 2
  • 15
  • 35
  • Unfortunately this will not work when hardware acceleration is enabled for the app. – Johann Jul 14 '21 at 14:48
  • Works in my App with Hardware acceleration as hardware acceleration is enabled by default for API >= 14. The other answer is accepted, so it works for other people as well. This is not taking a screenshot of a view that has been drawn to the screen already but drawing, measuring and laying out the view to an independent Canvas. – Andrew Jul 14 '21 at 15:55
  • It isn't clear in your code sample where you are getting the "view" from. You have a TableLayout defined twice making the sample difficult to follow. – Johann Jul 14 '21 at 16:43
  • Sorry I've extracted this from my App where the `TableLayout` is generated in a separate method which returns the View, I collapsed the example and forgot to align the names, now updated. – Andrew Jul 14 '21 at 20:51
  • I'll mark your solution as Accepted although it won't work if you are trying to create the view using Jetpack Compose running on Oreo and above, which is what I am attempting. Still, I can use the solution since it is possible to mix old xml views with Jetpack Compose. It'll do as a temporary solution. Thanks! – Johann Jul 15 '21 at 06:33
  • The question did not mention Jetpack Compose as the method of creating the UI, but thanks for the info that it won't work with this, so it sound like Jetpack Compose is something to avoid. – Andrew Jul 15 '21 at 07:36
  • The solution does work with Jetpack Compose, just not the way it's shown in your sample code. A ComposeView needs to be placed into a xml layout (or added programmatically to a view) and then you can pass the compose view as you do with a regular view, as shown in your sample. – Johann Jul 15 '21 at 10:49