Android 的 EditText 默认 cursor 是灰色,在浅色表单页里很容易看不清。TaoToken 是一个统一 API 兼容通道,我最近把 Codex 接到了 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content= 上,用同一把 Key 跑模型请求,然后让 Codex 直接帮我生成这段 cursor 样式代码。整个过程大概是:在官网创建 API Key,把 Base URL 填成 https://taotoken.net/api,然后让 Codex 按老流程输出 res/drawable/cursor.xml 和 android:textCursorDrawable="@drawable/cursor"。
你可能会问,改个光标有必要动用 Codex 吗?我的体会是,Android 里凡是这种“新建一个 drawable、再关联到属性”的重复操作,实际做起来非常机械:先想起来要建 cursor.xml,再查一遍 drawable 里的 shape 怎么写,最后还要确认 textCursorDrawable 有没有拼错。把这段交给 Codex 用自然语言描述,反而比自己在多个文件里切来切去更稳。TaoToken 在这里只负责提供模型 API,不参与你 Android 工程的任何部分;Codex 产出的文件最终还是要放在本地工程里 build 才能看到效果。
1. 默认 cursor 是灰色,textCursorDrawable 才是正确的修改口
1.1 先看清 EditText 的光标到底是什么
Android 的 EditText 默认光标是一根灰色短竖线,尺寸和颜色都受系统主题控制。你可以在 xml 里改变文本颜色、hint 颜色,但光标并不直接暴露一个cursorColor属性。真正被官方认可的方案,就是给android:textCursorDrawable指定一个 Drawable。这个 Drawable 的宽度决定光标粗细,颜色决定光标颜色;系统在绘制输入光标时会把它当作光标本体来用。
举例来说,原始需求是得到一根宽 1dp、颜色 #3399dd 的蓝色光标。那根灰色默认线的宽度大约 1-2dp,在浅色背景下并不醒目;改成品牌蓝后,用户能一眼看到当前输入位置。这个改动不涉及任何 Java/Kotlin 逻辑,纯粹是资源文件配置。很多人第一次查资料,找到的答案就是“新建 cursor.xml,再给 EditText 加属性”,但为什么这两步缺一不可,却很少被讲清楚。
1.2 为什么这件事适合交给 Codex 来生成
如果你已经习惯用 AI 写 UI 代码,就会发现这类任务很适合描述式生成:它不需要访问你的项目上下文,也不需要理解业务逻辑,只要告诉它“给 EditText 改光标:宽 1dp,颜色 #3399dd”,它就会按标准 Android 工程结构给出两个改动点。这里要解决的问题是怎样让 Codex 用上稳定的模型通道,而不是在几家厂商控制台之间来回切。TaoToken 提供的做法是:在 TaoToken 创建 Key,在 Codex 的 model provider 里填 Base URL,之后所有请求都会统一走这条通道,并且能在 TaoToken 后台看到调用记录。
2. 先在 TaoToken 建 Key,再把 Codex 指到 https://taotoken.net/api
2.1 从官网控制台复制 YOUR_API_KEY
准备材料其实就三样:一个 TaoToken 账号、一台装好 Codex CLI 的电脑、一个 Android 工程。第一件事打开 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content= ,注册登录后进入控制台,找到 API Keys 创建一个新 Key,复制出来的字符串就是 YOUR_API_KEY。创建时如果提供了备注名,建议写codex-android,方便后面在用量页里认出是哪条调用。
注意,这个 Key 会出现在你的 shell 配置或环境变量里,但千万别提交到 git,也不要贴到任何公共聊天窗口。如果你担心 Key 泄露,可以在控制台随时吊销重建;TaoToken 后台对每次调用都有记录,对账比本地日志清晰。
2.2 在 ~/.codex/config.toml 加一个 taotoken provider
Codex 的配置文件在用户目录下的~/.codex/config.toml。我们不要改全局默认 provider,而是新增一个名为taotoken的 provider,再让 model_provider 指向它。下面这段是可以直接放进 config.toml 的最小配置:
model_provider = "taotoken" [model_providers.taotoken] name = "TaoToken" base_url = "https://taotoken.net/api" env_key = "TAOTOKEN_API_KEY" wire_api = "chat"然后把 Key 放进环境变量:
export TAOTOKEN_API_KEY=YOUR_API_KEY这里base_url末尾没有/v1。Codex 会按自己的协议在/api后面拼具体路径;如果你手滑写成/api/v1,后面请求会落到不存在的路由上。官网地址只用于注册、创建 Key、看用量,不要填到配置文件里。
另外,模型 ID 不写死在配置里。Codex 支持用--model传模型名,你可以打开 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content= 的模型广场,从当前列出的模型里挑一个,把它的 ID 作为参数。这样做的好处是,TaoToken 后面上线新模型时,你不需要频繁改 config.toml,直接在命令行换一个模型 ID 就行。
3. 让 Codex 生成 res/drawable/cursor.xml 并给 EditText 挂上 textCursorDrawable
3.1 一句话说清需求,Codex 返回 cursor.xml
配置好之后,在项目根目录跑下面这条命令:
codex exec --skip-git-repo-check \ --model "模型ID,以模型广场列表为准" \ "在 Android 工程里新建一个 drawable 资源:路径是 res/drawable/cursor.xml,使用 rectangle shape,宽度为 1dp,颜色为 #3399dd;然后给出布局中 EditText 使用这个 drawable 的 textCursorDrawable 写法。"如果你更习惯交互式,直接执行codex然后把同样的话粘贴进去也行。Codex 会根据你的描述生成两样东西:一个cursor.xml,以及一行android:textCursorDrawable属性。下面这段就是它应当给出的资源文件内容:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="#3399dd" /> <size android:width="1dp" /> </shape>这里的逻辑对应原来的第一步:shape=rectangle是标准光标外形,size里的width=1dp控制光标粗细,color=#3399dd把灰色变成蓝色。Codex 如果生成的元素顺序不一样,不影响结果;真正影响最终渲染的是width和color两个值不能缺。
3.2 布局文件里补上 android:textCursorDrawable
第二步是给目标 EditText 加上属性。假设你的输入框叫et_search,那么在 layout 里应该看到类似这样的片段:
<EditText android:id="@+id/et_search" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="搜索商品" android:textCursorDrawable="@drawable/cursor" />属性名很长,容易拼错,正确的写法是android:textCursorDrawable,大小写和 CamelCase 都不能变。Codex 生成后,你不需要自己背这个属性,只要把这段粘贴到对应布局即可。如果你的 EditText 使用了AppCompatEditText或MaterialTextInputEditText,这个属性同样能传到原生绘制层,只是在某些 Material 主题下,光标高度会受到colorPrimary影响,看起来比纯原生 EditText 短一点。遇到这种情况,下一步再去改主题的colorControlActivated,就能一起解决。
3.3 Codex 只生成代码,不在你机器上执行
需要强调一点:Codex 做的事是生成、解释、对照 Android 代码,它不会替你运行 Gradle build,也不会把文件直接写进你的res/drawable目录,除非你显式让 Codex 的文件修改功能去创建,但那也要你自己确认。我在测试时是让 Codex 输出完整文件内容,再手动粘回 Android Studio 的。这样最稳妥,因为 Codex 没有连接你的 Android 工程或设备,它只通过 TaoToken 的 API 通道完成一次模型推理。你拿到的是一段可用的资源文件和属性,最终是否生效,由本地的 build 决定。
4. 回到 TaoToken 后台看这次调用,再在 Android Studio 里看光标
4.1 用量页里确认 Model 和状态
跑完上面的codex exec后,打开 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content= ,登录控制台进入用量或日志页面。你会看到刚才这次请求的记录,包括模型 ID、token 数量、返回状态。这一步相当于给“Codex 已经接到 TaoToken 上”上了一个保险:如果这里没有任何记录,说明请求没有真正发出,需要先检查 config.toml 里 base_url 是否写成了官网地址,或者环境变量有没有生效。
查看记录时,重点关注状态码是不是 200。Codex 一次完整请求通常对应多条 token 流式日志,在用量页里一般会聚合成一条调用记录。第一次跑通后,时间、模型 ID、输入输出 token 都能对得上,说明整条链路是通的。顺便也可以看看这次生成 cursor.xml 消耗的 token 数,对成本有个概念。
4.2 本机 build 后验证 #3399dd 是否生效
把res/drawable/cursor.xml放进工程,把android:textCursorDrawable="@drawable/cursor"写在目标 EditText 上,然后在 Android Studio 里 Sync 并运行 app。进入带有输入框的页面,点击输入框,光标应当从原来的灰色变成亮蓝色(#3399dd)。如果颜色变了但光标看不见,检查是否被软键盘挡住了;如果完全没变,跳到下一节的排障。
如果你想先在另一种界面里验证同一个 Key,也可以打开 TaoToken 模型对话 发同样的问题,看模型输出是否一致。这个页面用的是同一个 Key/账号体系,方便你排查是 Codex 配置问题还是模型本身问题。Key 的创建和吊销在 控制台 API Keys;如果你打算高频使用 Codex,可以再看看 Coding Plan 的套餐是否合适。
5. 光标没变或 Codex 报错?多半是这三个地方
5.1 Base URL 多写 /v1 时 Codex 会怎么错
最典型的配置错误是把https://taotoken.net/api写成https://taotoken.net/api/v1。Codex 的请求路径会变成/api/v1/chat/completions之类,而 TaoToken 实际提供的是/api/...。这种情况下用量页里可能看不到任何记录,codex 端会报 404 或 “not found”。解决办法就是把 config.toml 里的 base_url 改回/api,重启 Codex 再试。
5.2 drawable 没放进 res/drawable,textCursorDrawable 引用不到
文件生成后如果放错目录,比如放到res/drawable-v24/或res/mipmap/,编译不会报错,但@drawable/cursor可能引用到错误版本或者根本找不到。保证cursor.xml在app/src/main/res/drawable/下,文件命名全小写,不要用连字符或中文。另外,如果同一个工程里已经存在名为 cursor 的 drawable,你可以改用cursor_highlight之类的名字,然后同步修改布局里的@drawable/cursor_highlight。
5.3 codex 环境变量没带过去
使用codex exec时,如果是在当前终端里 export 的TAOTOKEN_API_KEY,但在另一个终端窗口启动 Codex,环境变量就丢失了。它会报认证失败,或者让你重新登录。把 export 写进~/.bashrc、~/.zshrc或你常用的 shell 配置文件,确保每次打开终端都能读到。不要直接把真实 Key 写在 config.toml 里,虽然某些 provider 支持,但环境变量方式更不容易泄露。
下次再遇到某个控件样式说不清,我会先把这个句子发给 Codex,让它把资源文件和属性写出来,然后在 TaoToken 后台对一下这次请求。你也可以把 Key 的名称改成codex-android,这样每次在控制台都清楚是哪条调用链。