根据用户给出的 Java/Kotlin 工具类或 View 相关源码,设计并实现 androidx.databinding.BindingAdapter。 工作区内优先 Read lib/DevSimple 下 bindingadapters;范例文件表见 references/reference.md。 过滤不适合 XML 的 API;Long? 时间戳、Boolean? 三态、attribute 合并(参照 XYI);成稿按 code-method-normalize。 在用户要求生成 BindingAdapter、补全 DataBinding 属性、或评审 DevSimple bindingadapters 时使用。
75
93%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
| 符号 | 当前值(DevUtils) |
|---|---|
DEVSIMPLE_ROOT | lib/DevSimple |
BINDING_VIEW_DIR | {DEVSIMPLE_ROOT}/src/main/java/dev/simple/bindingadapters/view |
BINDING_ATTR_DIR | {DEVSIMPLE_ROOT}/src/main/java/dev/simple/bindingadapters/view/attribute |
存在 {DEVSIMPLE_ROOT} 时 Read 本地 *.kt,勿用 WebFetch 代替。生成前在 {BINDING_VIEW_DIR} 下列出并对照现有实现;优先范例文件名、前缀惯例、判定表 → references/reference.md。
上游 fallback(仅工作区无模块时):https://github.com/afkT/DevUtils/tree/master/lib/DevSimple
生成或改写 方法体与文档 时,同时 Read 并遵守:
<pre>、首段规则、@param/@return、boolean 对举、异常内消化等)本 Skill 负责 「是否该做 BindingAdapter、属性如何设计、时间戳与合并参数」;文档句式交给 code-method-normalize。
{BINDING_VIEW_DIR} 下与目标控件相关的 *.kt(至少一份同族文件 + references/reference.md §优先范例 中对应行)。{BINDING_ATTR_DIR};XYI 等写法对照同目录 XYI.kt。View.kt 为准(路径见 reference)。BindingAdapter 绑定在 布局里的单个 View 节点;只封装 对该接收者 View(及合理子类型)有意义、且能在 XML 表达参数 的操作。
应跳过或不要求用户封装(与 View.kt 文件头说明一致)的典型类别:
inflate 等getActivity 等getChildAt 等(除非业务明确绑定的是容器且参数是 index,再按列表类控件单独设计)convertViewGroup 等适合封装的正向例子:removeAllViews、requestLayout、setText、滚动到某位置、设置可见性、设置图片资源等——参数为基本类型、String、Drawable、XYI 等可在 Binding / LiveData 中传递的类型。
若某方法 仅 View/TextView/… 一个参数,除「纯状态同步」(如设置某个由 XML 已绑定的 bool)外,重复触发(同值不刷新)往往成问题 → 见第 2 节 时间戳。
Long? 时间戳触发当底层 API 形如 FooUtils.action(view) 仅有当前接收者、无业务参数,又需要在 MVVM 里 多次触发同一逻辑(例如再次滑到底、再次清空)时:
timestamp: Long?(或与其它参数组合时,时间戳作为触发列之一)<pre> 中写明:建议绑定 System.currentTimeMillis() 或 ViewModel 内递增时间戳;优于 LiveData<Boolean> 固定 true 不二次刷新成对语义(示例):已有 EditTextUtils.setText(view, text) 对应「设文本」;可另增 「清空文本」 适配器,入参仅为 timestamp: Long?,内部在通过校验后调用 EditTextUtils.setText(view, "")(或项目等价 API)。文档中说明与 binding_et_text 等的关系,避免重复绑定冲突。
当底层工具类提供 成对的 set / remove(或语义等价的 enable / disable)API,且布局需要绑定 可切换、可保持的 View 效果(下划线、删除线、paintFlags 装饰、部分可见性样式等)时:
Boolean?(不用非空 Boolean,以便区分「未绑定」与「显式关闭」)。null → return,不修改 View(未提供 LiveData、或尚未赋值时保留 XML / 主题默认)。true → 调用 开启 / 设置 API(如 TextViewUtils.setUnderlineText)。false → 调用 关闭 / 移除 API(如 TextViewUtils.removeUnderlineText)。与 §2 时间戳 的分工:
| 场景 | 选用 |
|---|---|
| 需要 同步并保持 开/关状态,随 DataBinding 刷新更新 UI | Boolean? 三态(本节) |
| 无状态,每次都要 再触发一次 副作用(再次滚到底、再次清空) | Long? 时间戳(§2) |
工具类 仅有 set、无 remove,且 false 语义就是「不做事」 | 可 Boolean? 仅 true 时执行;若业务要在布局里 关掉 已有效果,应补 remove 工具方法后改本节三态 |
禁止:底层已有 removeXxx 时仍写 if (flag != true) return,导致布局绑 false 无法撤销效果。
仓库参考实现:TextView.bindingTVUnderline、TextView.bindingTVStrikeThru(见 {BINDING_VIEW_DIR}/TextView.kt,reference §优先范例)。
fun TextView.bindingTVUnderline(
underline: Boolean?,
antiAlias: Boolean?,
) {
if (underline == null) return
if (underline) {
TextViewUtils.setUnderlineText(this, antiAlias ?: true)
} else {
TextViewUtils.removeUnderlineText(this)
}
}antiAlias)仅在 true 开启分支 使用;requireAll = false 时缺省与工具类一致。<pre> 中写明三态与对应的 set* / remove* 工具方法名。逻辑统一为:非 null 且大于 0 才执行。
本仓库已有:
fun Long?.qualifiesScroll(): Boolean = this != null && this > 0L新代码若语义不是滚动(避免命名误导),可在同一模块抽取例如:
/** 数据绑定用:时间戳非空且大于 0 时执行一次副作用。 */
fun Long?.qualifiesBindingAction(): Boolean = this != null && this > 0L具体命名与存放文件随模块惯例;禁止用 <=0 或 null 仍执行(除非项目已有特例并在备注中写明)。
避免 多个密切相关、应同事务触发的量拆成多个 binding_*,导致 多次调用适配器、LiveData 数量膨胀。
做法:
dev.simple.bindingadapters.view.attribute(即 {BINDING_ATTR_DIR},或用户指定包的 attribute 子包)新增 Kotlin data class / open class,字段覆盖原工具方法参数(含可选默认值)。@BindingAdapter("binding_…_single_snake_name"),入参为该类型可空;null 时跳过。XYI);补充 equals/hashCode(data class 自带)、toString、伴生工厂方法视需要。binding_scroll_instant_rel_dx + binding_scroll_instant_rel_dy(requireAll = false)改为 binding_scroll_instant_rel_xy + XYI?(见用户提供的旧/新对照)。app:binding_snake_case;@BindingAdapter 的 value 与之一致。fun View.bindingCamelCase(...),与文件内现有风格一致。requireAll = false 仅当 确有独立缺省语义 时使用;能合并为实体类则优先合并。Boolean 表示是否执行/成功,并满足 code-method-normalize 中 boolean/Boolean 的 @return 写法。public/internal 方法。View / TextView / ImageView / ViewGroup / RecyclerView 等)、参数拆分或合并(第 4 节)、是否需要时间戳(第 2 节)或 Boolean 三态开关(第 2.5 节)。{BINDING_VIEW_DIR}/(按控件分文件,与现有 TextView.kt、ViewScroll.kt 等并列);attribute 类写入 {BINDING_ATTR_DIR}/。code-method-normalize 并整理文档与返回类型。@BindingAdapter 不与 {BINDING_VIEW_DIR} 内已有属性名冲突;try/catch 与日志风格参照 reference 中 TextView / ImageViewLoadNative 范例。判定表、XML 示例、binding_* 前缀表见 references/reference.md。
{BINDING_VIEW_DIR} 或 reference §优先范例,而非仅凭记忆写适配器。binding_* 冲突。{BINDING_ATTR_DIR};成稿前已 Read code-method-normalize。3fa9400
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.