I got into a bit of trouble when I tried to create a dynamic layout and generate a Bitmap without displaying it on the screen, so I'll leave this as a note.
fun createLayoutBitmap() {
val frameLayout = createMeasuredFrameLayout()
val bitmap = createBitmap(frameLayout)
// save bitmap or set Views ...
}
fun createMeasuredFrameLayout(): FrameLayout {
// inflate or new your layout
return FrameLayout(context).apply {
setBackgroundColor(Color.YELLOW)
val tv = TextView(context).apply {
text = "test"
}
// apply pixel size to TextView
addView(tv, Rect(0, 0, 100, 200).toLayoutParams())
// important: you need call measure() after build layout. do not add after measure(). my mistaken point.
measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}
}
fun createBitmap(view: View): Bitmap {
// apply drawing bitmap size in pixel.
val rect = Rect(0, 0, 500, 500)
return Bitmap.createBitmap(rect.width(), rect.height(), Bitmap.Config.ARGB_8888).also {
view.layout(rect.left, rect.top, rect.width(), rect.height())
view.draw(Canvas(it))
}
}
// rect is intuitive.
fun Rect.toLayoutParams(): ViewGroup.LayoutParams {
return FrameLayout.LayoutParams(width(), height()).apply {
leftMargin = left
topMargin = top
}
}
this is a very easy sample code.