ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Android EditText 光标消失排查与 textCursorDrawable 自定义实战:TaoToken 统一 Key 配置骨架

2026/9/29 22:26:16 拓冰建站 浏览量
Android EditText 光标消失排查与 textCursorDrawable 自定义实战:TaoToken 统一 Key 配置骨架 1. 光标不见了先别急着改代码Android 里 EditText 不显示光标是个看起来很小、排查起来很烦的问题。它不像崩溃那样有堆栈也不像布局错位那样一眼能看出来很多时候就是输入框能打字、能选中、能弹键盘唯独那根竖线不见了。你盯着屏幕怀疑人生切到别的 App 发现人家光标好好的于是开始怀疑是不是系统版本问题、是不是输入法问题。我先把结论放前面绝大多数「EditText 不显示光标」都不是系统 bug而是背景、主题、inputType、padding、focusable 这几个东西里有一个把光标盖住或者干掉了。而「自定义光标」这件事本身Android 早就给了官方属性android:textCursorDrawable不需要反射、不需要改源码一个 drawable 就能换颜色换形状。这篇会按两条线走。第一条线是排查从焦点、主题、inputType、背景、padding 逐层定位告诉你每一步看什么、改什么。第二条线是自定义给出textCursorDrawable的完整可复制配置包括纯色光标、带圆角的粗光标、以及用 shape 画出来的光标。中间会穿插一个统一 Key/API 通道的配置骨架方便你在写 Demo 验证光标显隐时顺手把模型调用通道也接上不用每次换项目都重新找 Key。适合谁看正在做 Android 输入框、搜索框、验证码框的开发者被自定义背景坑过光标的人以及想给光标换个颜色但不想引入第三方库的人。下面所有代码都可以直接贴进项目跑验证动作我也会写清楚——运行 Demo点进输入框看光标有没有出现、样式有没有切换。2. 把 TaoToken 作为统一 Key 通道接进 Demo排查光标问题时我习惯写一个最小 Demo只放一个 EditText 加几个开关按钮用来切换背景、padding、inputType观察光标变化。这个 Demo 如果还要顺带验证「输入内容后请求模型」就会涉及 API Key 管理。与其在每个 Demo 里硬编码 Key不如用一个统一通道把 Key 和 base URL 收在一处。TaoToken 在这里的角色就是统一 Key/API 通道官网是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 。它的价值不是替你写 Android 代码而是让你在 Demo、脚本、IDE 插件里用同一套 Key 和同一个 base URL换项目时只改配置不改逻辑。你需要先拿到 Key。进入控制台创建 API Key地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 创建后复制那串sk-开头的字符串。注意它只在创建时完整显示一次先存到安全的地方。Key 的管理页面在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 后面要轮换或删除都从这里进。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面写了 base URL 和兼容的请求格式。如果你用的是 Claude Code 这类编码工具Anthropic 兼容入口在 https://taotoken.net/ClaudeCodeAnthropic?utm_sourcetaotoken_aicg_blog_endutm_contentClaudeCodeAnthropicutm_campaignrewrite 。想先不写代码、直接在网页里试模型对话用 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。长期做编码或 Agent 任务可以看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。下面给两个配置骨架一个是给编辑器/插件用的settings.json一个是给命令行工具用的config.toml。它们和光标排查没有直接关系但能让你在 Demo 里加「请求模型」按钮时不用再折腾鉴权。{ apiKey: sk-你的Key, baseUrl: https://taotoken.net/api, model: claude-sonnet-4-20250514, timeoutMs: 30000 }[provider] api_key sk-你的Key base_url https://taotoken.net/api model claude-sonnet-4-20250514 timeout_ms 30000把 Key 放在配置文件里代码里只读配置这样 Demo 删了重建也不影响。注意不要把 Key 提交到公开仓库本地用.gitignore排除掉。3. 光标消失的五类原因与逐层排查3.1 焦点没拿到光标自然不出现光标是焦点的可视化表现。EditText 没有焦点就不会画光标。常见情况是外层容器设置了android:focusabletrue或者android:focusableInTouchModetrue把焦点抢走了。比如 ScrollView 里套 EditTextScrollView 默认在触摸模式下可获焦点进去焦点落在 ScrollView 上EditText 就没光标。排查动作在布局里给 EditText 加android:focusabletrue和android:focusableInTouchModetrue同时检查父容器有没有抢焦点。更直接的办法是在代码里打印当前焦点editText.setOnFocusChangeListener { v, hasFocus - Log.d(CursorDebug, hasFocus$hasFocus, isFocused${v.isFocused}) }如果点进去hasFocus一直是 false那就是焦点被上层拿走了。把父容器的focusable去掉或者在触摸时手动editText.requestFocus()。3.2 主题里的 colorControlActivated 把光标颜色设成了透明Android 5.0 之后EditText 光标颜色默认跟随主题的colorControlActivated。如果你在主题里把这个颜色设成了透明或者设成了和背景一样的颜色光标就「隐身」了。这种情况在自定义主题、深色模式切换时特别常见。排查动作打开res/values/themes.xml看colorControlActivated的值。如果它是android:color/transparent或者和输入框背景同色改成对比色。style nameAppTheme parentTheme.MaterialComponents.DayNight item namecolorControlActivated#FF0000/item /style改完运行 Demo点进输入框光标应该变成红色。如果还是不见继续往下看。3.3 inputType 设成 none光标被禁用android:inputTypenone会让 EditText 不可编辑光标也不会显示。有些同学为了「只显示不输入」把 inputType 设成 none结果发现光标没了还以为是 bug。另外android:editablefalse也有同样效果。排查动作检查布局里 EditText 的inputType确保是text、number、textPassword这类可编辑类型。如果确实需要不可编辑那光标不显示是正常行为不用修。3.4 图片背景盖住光标这是最经典的一类。EditText 用了图片背景图片不透明光标画在背景之上但被图片的某些区域遮住看起来就像消失了。excerpt 里提到的android:textCursorDrawablenull就是针对这种情况把光标 drawable 设为 null系统会用默认光标同时不再受自定义背景的绘制顺序影响。排查动作先把背景临时改成纯色#FFFFFF看光标是否出现。如果出现说明是背景图的问题。解决办法有两个一是给背景图中间留透明区域二是设置android:textCursorDrawablenull让系统用默认光标。EditText android:layout_widthmatch_parent android:layout_heightwrap_content android:backgrounddrawable/bg_input android:textCursorDrawablenull android:paddingLeft12dp android:paddingRight12dp /3.5 shape 背景加 padding 缺失光标被边框覆盖用 shape 画背景时如果边框比较粗又没有设置 padding光标会紧贴左边框被边框盖住。excerpt 里强调的「padding 值很重要」就是这个意思。shape 的中间区域要透明边框和光标之间要有间距。排查动作给 EditText 加左右 padding至少 5dp边框粗的话加到 8dp 以上。EditText android:layout_widthmatch_parent android:layout_heightwrap_content android:backgrounddrawable/bg_shape android:paddingLeft8dp android:paddingRight8dp android:textCursorDrawablenull /对应的 shapeshape xmlns:androidhttp://schemas.android.com/apk/res/android solid android:color#00000000 / stroke android:width2dp android:color#333333 / corners android:radius6dp / /shape中间solid用透明色边框 2dppadding 8dp光标就不会被盖住。4. textCursorDrawable 自定义光标完整配置排查完显隐问题接下来是自定义样式。android:textCursorDrawable接收一个 drawable 资源 ID你可以用 shape 画一个纯色光标、圆角光标、甚至带渐变的粗光标。注意这个属性在 API 29 及以上才完全生效低版本部分机型可能忽略所以自定义前先确认 minSdk。4.1 纯色细光标最简单的自定义把光标改成蓝色宽度 2dp。!-- res/drawable/cursor_blue.xml -- shape xmlns:androidhttp://schemas.android.com/apk/res/android android:shaperectangle size android:width2dp / solid android:color#2196F3 / /shapeEditText android:layout_widthmatch_parent android:layout_heightwrap_content android:textCursorDrawabledrawable/cursor_blue android:paddingLeft8dp android:paddingRight8dp /运行 Demo点进输入框光标应该是蓝色细线。如果没变化检查是否被主题的colorControlActivated覆盖或者当前 API 版本不支持。4.2 圆角粗光标想要更明显的粗光标把宽度加到 4dp加圆角。!-- res/drawable/cursor_round.xml -- shape xmlns:androidhttp://schemas.android.com/apk/res/android android:shaperectangle size android:width4dp / solid android:color#FF5722 / corners android:radius2dp / /shapeEditText android:layout_widthmatch_parent android:layout_heightwrap_content android:textCursorDrawabledrawable/cursor_round android:paddingLeft8dp android:paddingRight8dp /圆角半径不要超过宽度的一半否则形状会变形。4dp 宽配 2dp 圆角看起来是圆头竖条。4.3 用代码动态切换光标样式有时候需要在运行时切换光标比如夜间模式换颜色。textCursorDrawable是 XML 属性代码里可以用setTextCursorDrawableAPI 29。if (Build.VERSION.SDK_INT Build.VERSION_CODES.Q) { editText.setTextCursorDrawable(R.drawable.cursor_round) }低版本没有这个 API只能通过主题或重新 inflate 布局实现。如果你的 minSdk 低于 29建议在 XML 里定好样式运行时切换用两套主题。4.4 验证动作运行 Demo 检查显隐与样式把上面几个 drawable 都放进项目写一个按钮循环切换var index 0 val cursors listOf( R.drawable.cursor_blue, R.drawable.cursor_round, R.drawable.cursor_default ) btnSwitch.setOnClickListener { index (index 1) % cursors.size if (Build.VERSION.SDK_INT Build.VERSION_CODES.Q) { editText.setTextCursorDrawable(cursors[index]) } editText.requestFocus() editText.setSelection(editText.text.length) }运行后点按钮光标颜色和粗细应该跟着变。如果不变先确认 API 版本再确认 EditText 有焦点。这个验证动作能同时覆盖「光标显隐」和「样式切换」两件事。5. 本篇常见错排查5.1 设置了 textCursorDrawable 但没效果先看 API 版本。textCursorDrawable在低版本上部分机型不生效尤其是 API 28 以下。其次看主题如果主题里colorControlActivated被硬编码可能覆盖 drawable。最后看 drawable 本身shape 的size宽度如果是 0 或者没写光标可能画不出来。5.2 光标颜色和背景一样这是主题色问题不是 drawable 问题。检查colorControlActivated和colorAccent确保它们和输入框背景有对比。深色模式下尤其容易踩因为背景变深、光标颜色没跟着变。5.3 光标被键盘遮住这不是光标消失是布局被键盘顶上去后光标跑到可视区域外。在AndroidManifest.xml里给 Activity 设android:windowSoftInputModeadjustResize让布局随键盘调整。activity android:name.MainActivity android:windowSoftInputModeadjustResize /5.4 多个 EditText 只有一个有光标正常现象。同一时间只有一个 View 持有焦点光标只画在焦点 View 上。如果你希望每个输入框都有「光标感」可以用自定义背景模拟但真正的光标只有一个。5.5 自定义光标在部分机型上变粗或变细不同厂商对textCursorDrawable的渲染有差异尤其是宽度。建议用 dp 而不是 px宽度不要小于 2dp否则在高密度屏上可能看不见。如果对一致性要求高可以在代码里根据density动态调整 drawable 宽度。6. 把 Key 配置和光标 Demo 收在一起光标排查这件事本质是「逐层排除」焦点、主题、inputType、背景、padding一层层看过去总能找到那个把光标藏起来的东西。自定义光标反而是最简单的部分一个textCursorDrawable加一个 shape 就够不需要反射也不需要第三方库。如果你在 Demo 里加了模型请求按钮Key 和 base URL 建议统一走 TaoToken 通道。模型对话入口在 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite Key 管理在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。长期做编码或 Agent 任务Coding Plan 在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。最后留一个我踩过的坑用 shape 做背景时solid一定要写透明色#00000000不写的话默认是黑色光标直接被黑底吞掉。这个坑我调了半小时才反应过来希望你别再花这半小时。