我需要迁移我的旧java代码,该代码创建一个Drawable实例,它是一个渐变,其起始颜色在上部,结束颜色在底部。
它在 java 中运行得很好,但是将代码迁移到 kotlin 并进行 compose 后,getDrawable 函数返回一个空的透明可绘制对象:
override fun getDrawable(): Drawable {
val sf: ShaderFactory = object : ShaderFactory() {
override fun resize(width: Int, height: Int): Shader {
return LinearGradient(
startX(width), startY(height), endX(width), endY(height), intArrayOf(
color1, color2
),
null, Shader.TileMode.MIRROR
)
}
}
val p = PaintDrawable()
p.shape = RectShape()
p.shaderFactory = sf
return p
}
fun startX(actualWidth: Int): Float {
when (type) {
Type.SOLID -> return 0f
Type.DEGREE_DOWN_UP, Type.DEGREE_UP_DOWN -> return actualWidth / 2.0f
Type.DEGREE_LEFT_RIGHT -> return 0.0f
Type.DEGREE_RIGHT_LEFT -> return actualWidth.toFloat()
else -> {}
}
return (-1).toFloat()
}
fun startY(actualHeight: Int): Float {
when (type) {
Type.SOLID -> return 0f
Type.DEGREE_DOWN_UP -> return actualHeight.toFloat()
Type.DEGREE_LEFT_RIGHT, Type.DEGREE_RIGHT_LEFT -> return actualHeight / 2.0f
Type.DEGREE_UP_DOWN -> return 0f
else -> {}
}
return (-1).toFloat()
}
fun endX(actualWidth: Int): Float {
when (type) {
Type.SOLID -> return actualWidth.toFloat()
Type.DEGREE_DOWN_UP, Type.DEGREE_UP_DOWN -> return actualWidth / 2.0f
Type.DEGREE_LEFT_RIGHT -> return actualWidth.toFloat()
Type.DEGREE_RIGHT_LEFT -> return 0f
else -> {}
}
return (-1).toFloat()
}
fun endY(actualHeight: Int): Float {
when (type) {
Type.SOLID -> return actualHeight.toFloat()
Type.DEGREE_DOWN_UP -> return 0f
Type.DEGREE_UP_DOWN -> return actualHeight.toFloat()
Type.DEGREE_LEFT_RIGHT, Type.DEGREE_RIGHT_LEFT -> return actualHeight / 2.0f
else -> {}
}
return (-1).toFloat()
}
drawable 的类型是
DEGREE_UP_DOWN
这就是我使用可绘制对象的方式:
val bg = GradientShading(Shading.Type.DEGREE_UP_DOWN, topColor, bottomColor)
LazyColumn(
modifier = modifier.fillMaxWidth()
.clipToBounds()
.drawBehind {
drawIntoCanvas { bg.getDrawable().draw(it.nativeCanvas) }
},
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Top
)
代码有什么问题?
这是代码的工作 java 版本,显然是完全相同的:
@Override
public Drawable getDrawable() {
ShapeDrawable.ShaderFactory sf = new ShapeDrawable.ShaderFactory() {
@Override
public Shader resize(int width, int height) {
LinearGradient lg = new LinearGradient(startX(width), startY(height), endX(width), endY(height), new int[] {
color1 , color2 },
null, Shader.TileMode.MIRROR);
return lg;
}
};
PaintDrawable p = new PaintDrawable();
p.setShape(new RectShape());
p.setShaderFactory(sf);
return (Drawable)p;
}
float startX(int actualWidth) {
switch (this.type) {
case SOLID:
return 0;
case DEGREE_DOWN_UP:
case DEGREE_UP_DOWN:
return actualWidth/2.0f;
case DEGREE_LEFT_RIGHT:
return 0.0f;
case DEGREE_RIGHT_LEFT:
return actualWidth;
}
return -1;
}
float startY(int actualHeight){
switch (this.type) {
case SOLID:
return 0;
case DEGREE_DOWN_UP:
return actualHeight;
case DEGREE_LEFT_RIGHT:
case DEGREE_RIGHT_LEFT:
return actualHeight/2.0f;
case DEGREE_UP_DOWN:
return 0;
}
return -1;
}
float endX(int actualWidth){
switch (this.type) {
case SOLID:
return actualWidth;
case DEGREE_DOWN_UP:
case DEGREE_UP_DOWN:
return actualWidth/2.0f;
case DEGREE_LEFT_RIGHT:
return actualWidth;
case DEGREE_RIGHT_LEFT:
return 0;
}
return -1;
}
float endY(int actualHeight){
switch (this.type) {
case SOLID:
return actualHeight;
case DEGREE_DOWN_UP:
return 0;
case DEGREE_UP_DOWN:
return actualHeight;
case DEGREE_LEFT_RIGHT:
case DEGREE_RIGHT_LEFT:
return actualHeight/2.0f;
}
return -1;
}
在调用
nativeCanvas.clipBounds
之前将 drawable.bounds
分配给 drawable.draw
,如下所示:
val drawable = remember { GradientShading(Color.BLUE, Color.MAGENTA).getDrawable() }
LazyColumn(modifier = Modifier
.fillMaxWidth()
.clipToBounds()
.drawBehind {
drawIntoCanvas { canvas ->
drawable.bounds = canvas.nativeCanvas.clipBounds
drawable.draw(canvas.nativeCanvas)
}
}
) {
items(10) { Text("Item $it") }
}
我的
GradientShading
类重构为DEGREE_UP_DOWN
(getDrawable
方法相同):
private class GradientShading(val color1: Int, val color2: Int) {
fun getDrawable(): Drawable {
val sf: ShaderFactory = object : ShaderFactory() {
override fun resize(width: Int, height: Int): Shader {
return LinearGradient(
startX(width), startY(height), endX(width), endY(height), intArrayOf(
color1, color2
),
null, Shader.TileMode.MIRROR
)
}
}
val p = PaintDrawable()
p.shape = RectShape()
p.shaderFactory = sf
return p
}
fun startX(actualWidth: Int): Float {
return actualWidth / 2.0f
}
fun startY(actualHeight: Int): Float {
return 0f
}
fun endX(actualWidth: Int): Float {
return actualWidth / 2.0f
}
fun endY(actualHeight: Int): Float {
return actualHeight.toFloat()
}
}
结果: