安卓视图与可组合视图的比较



在视图世界中,我们可以使用view.draw(画布(在画布上绘制视图(可能连接到位图(。但在写作中,我们如何才能做到这一点。

我们有一个draw修饰符,但它没有方法draw(canvas(

更新

我需要什么

我想通过将可组合函数包装在模糊可组合函数中来模糊它。假设xyz((是任意一个随机组合标签函数。

@Composable
fun xyz(){
// compose logic.
}

我想创造另一种乐趣,叫做Blur((。

@Composable
fun Blur(content: @Composable() -> Unit){
//Blur logic.
}

Blur可组合函数接受任何可组合函数(比如xyz(((作为输入并对其进行模糊处理。

我将如何实施它

我想我会采用与BlurView(视图模糊库(相同的方法。

  • 模糊视图是一个框架布局
  • 它模糊了内容
  • BlurView首先创建内容的位图;模糊了它;然后绘制
  • 用于创建内容位图的函数是view.draw(canvas: Canvas)

为什么我需要这个

我想在compose中创建我的BlurView版本。我知道在创作中有一个Modifier.blur;但由于这只在api 31中得到支持(我想(,所以我不能在我的项目中使用它。

Compose中,有一个Canvas可组合函数可用于DrawScope。你可以利用它来画画。

DrawScope具有drawImage函数来获取ImageBitmap。正如你有位图需要转换使用Bitmap.asImageBitmap()

正如在另一个回复中所指出的,您可以创建一个使用画布的可组合文件,这将使您能够访问与常规View画布中相同的许多绘图方法。

@Composable
fun MyCanvasComposable(
data: List<Int>, //some example data to pass in
modifier: Modifier = Modifier
) {
Canvas() {
.. content here     
}
}

在画布中,您将进入DrawScope,它将允许您像以前一样进行画布绘制。

我将添加一些示例,假设我们将绘图逻辑引入到扩展方法中。

示例:

绘制一些文本

internal fun DrawScope.drawSomeText() {
//some logic here before drawing the text
drawContext.canvas.nativeCanvas.drawText(
[[your text]],
positionX,
positionY,
paint
)
}

绘制路径

internal fun DrawScope.plotXAxis(    
//some custom rendering here followed by this method    
drawPath(path, pathBrush, 0.5f)
}

为了将画布放在另一个布局上,您可以使用适当的布局修饰符调用MyCanvasComposable

如果你想在画布上渲染其他可组合的东西,你可以把整个东西包在一个盒子里,然后在画布绘制之前或之后添加视图。

示例:

val myPainter = painterResource(id = R.drawable.src_image)
Box {
Image(
painter = myPainter
)
Canvas() {
.. content here ..
}
Text( "some text")
}

在上面的例子中,您也可以只调用MyCanvasComposable而不是Canvas((

还请注意,图像将在画布之前渲染,文本则在画布之后渲染,也就是说在画布顶部。

如果您想要从View函数或这里提到的RenderScript等方法中模糊Bitmap,并在其上绘制地标或形状,您可以使用androidx.compose.ui.graphics.Canvas代替androidx.compose.foundation.Canvas

val option = BitmapFactory.Options()
option.apply {
inPreferredConfig = Bitmap.Config.ARGB_8888
inMutable = true
}
val imageBitmap = RenderEffect.createBitmapEffect(Bitmap bitmap)

对于api 31-

private Bitmap blur(Bitmap original, float radius) {
Bitmap bitmap = Bitmap.createBitmap(
original.getWidth(), original.getHeight(),
Bitmap.Config.ARGB_8888);
RenderScript rs = RenderScript.create(this);
Allocation allocIn = Allocation.createFromBitmap(rs, original);
Allocation allocOut = Allocation.createFromBitmap(rs, bitmap);
ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(
rs, Element.U8_4(rs));
blur.setInput(allocIn);
blur.setRadius(radius);
blur.forEach(allocOut);
allocOut.copyTo(bitmap);
rs.destroy();
return bitmap;
} 

我现在不在我的电脑上,当我有空的时候,我会添加它作为修改器。

// 🔥 This is a function that returns Canvas which can be used to draw on an
// ImageBitmap that was sent as param. ImageBitmap that returned can be
// be used to display on Image or can be saved to a physical file.
val canvas: androidx.compose.ui.graphics.Canvas = Canvas(imageBitmap)
val paint = remember {
Paint().apply {
style = PaintingStyle.Stroke
strokeWidth = 10f
color = Color(0xff29B6F6)
}
}
canvas.drawRect(0f, 0f, 200f, 200f, paint = paint)
canvas.drawCircle(
Offset(
imageBitmap.width / 2 - 75f,
imageBitmap.height / 2 + 75f
), 150.0f, paint
)

// This bitmap has image and the drawing from canvas
Image(bitmap = imageBitmap, contentDescription = null)

最新更新