根据用户给出的 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 时使用。
74
93%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
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。afkT/DevUtils
6022ede
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.