You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何监听自定义控件onClick事件,实现选中图形移动及GradientDrawable.RingShape显示

1. 选中对象移动功能实现

核心改动点:

  • 给Dot类增加选中状态回调,和Activity的selectedCompound联动
    修改Dot类构造:
open class Dot(
    context: Context, 
    val parent: RelativeLayout, 
    var x: Int, 
    var y: Int,
    private val onSelectStateChanged: (Dot, Boolean) -> Unit
) : View(context), Graphic, View.OnClickListener {
    // 原有代码不变
    override fun onClick(v: View?) {
        isClicked = !isClicked
        dotDrawable.setColor(if(isClicked) Color.RED else Color.BLACK)
        // 通知上层选中状态变更
        onSelectStateChanged.invoke(this, isClicked)
    }
}

Circle类构造同步加回调参数:

class Circle(
    context: Context, 
    parent: RelativeLayout, 
    x: Int, 
    y: Int, 
    var radius: Int,
    onSelectStateChanged: (Dot, Boolean) -> Unit
) : Dot(context, parent, x, y, onSelectStateChanged) {
    // 原有代码不变
}
  • Activity中初始化图形时绑定回调,维护selectedCompound
// 初始化Dot示例
val dot = Dot(this, parent, 100, 100) { graphic, isSelected ->
    if (isSelected) {
        selectedCompound.add(graphic)
    } else {
        selectedCompound.remove(graphic)
    }
}
// Circle和其他图形初始化逻辑同理
  • 修改移动按钮逻辑,支持选中对象移动
    以下为优先移动选中对象的逻辑,也可自行增加切换按钮分别控制移动全部/选中对象:
moveButton.setOnClickListener {
    val x = xField.text.toString().toIntOrNull() ?: 0
    val y = yField.text.toString().toIntOrNull() ?: 0
    if (selectedCompound.children.isNotEmpty()) {
        selectedCompound.move(x, y)
    } else {
        allCompound.move(x, y)
    }
}

2. GradientDrawable RingShape不显示问题解决

之前设置不生效是因为Ring类型必须主动设置尺寸,正确实现代码如下:

val ringDrawable = GradientDrawable().apply {
    shape = GradientDrawable.RING
    setColor(Color.TRANSPARENT) // 内部填充透明
    setStroke(20, Color.BLACK) // 环描边颜色、宽度
    innerRadiusRatio = 2f // 内半径 = 总宽度 / innerRadiusRatio,数值越大内半径越小
    thicknessRatio = 4f // 环厚度 = 总宽度 / thicknessRatio,数值越大环越细
    setSize(400, 400) // 必须设置固定尺寸,否则默认宽高为0无法显示
}

3. 组合模式演示优化建议

  • 解耦平台逻辑:把Graphic接口做成纯业务抽象,不继承Android View、不持有Context,单独抽渲染层负责Android端绘制,核心组合逻辑和平台无关,更能突出设计模式本身的结构。
  • 消除重复代码:Dot和Circle的move逻辑高度重复,可以把LayoutParams抽到父类作为open变量,move逻辑统一在父类实现,子类只需要修改对应LayoutParams参数即可。
  • 优化移动性能:移动时不需要反复removeView+addView,直接修改LayoutParams的margin值后调用requestLayout()即可,渲染效率更高。
  • 支持组合选中:给Graphic接口增加isSelected属性,CompoundGraphic实现选中逻辑时可以递归处理子元素的选中状态,实现“选中整个组合、移动整个组合”的特性,完全贴合组合模式单个对象和组合对象使用一致的核心设计。

我的应用截图

内容的提问来源于stack exchange,提问作者Nero Nguyen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 08:45:04