You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

制作‘填空’测验的最优方案及TextView排版异常问题求助

嘿,我完全懂你遇到的困扰——用三个独立的TextView做填空测验,确实会碰到文本换行不连贯的问题,毕竟每个TextView都是单独的布局元素,系统根本不会把它们当成一段连续的文本流来处理。咱们来聊聊几个更靠谱的实现方案:

方案1:单个TextView + SpannableString(适合纯展示类填空)

把整个句子塞进一个TextView里,用SpannableString标记填空区域,这样文本会自然连贯换行,完全解决你之前的换行问题。示例代码如下:

String fullSentence = "The quick brown ___ jumps over the lazy dog, and then runs away to the ___.";
SpannableString spannable = new SpannableString(fullSentence);

// 定位所有"___"填空标记,替换成带样式的空白区域
Pattern pattern = Pattern.compile("___");
Matcher matcher = pattern.matcher(fullSentence);
while (matcher.find()) {
    int start = matcher.start();
    int end = matcher.end();
    // 添加下划线模拟填空框
    spannable.setSpan(new UnderlineSpan(), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    // 可选:添加浅灰色背景让填空区域更醒目
    spannable.setSpan(new BackgroundColorSpan(Color.LTGRAY), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}

textView.setText(spannable);

方案2:EditText + Spannable(支持用户输入填空)

如果需要用户能在填空区域输入内容,单个EditText配合Spannable是最优解——既保持文本连贯,又能让用户在指定位置输入:

String fullSentence = "My favorite programming language is ___ because it's ___.";
EditText editText = findViewById(R.id.edit_text);

// 初始化带填空标记的文本
SpannableString spannable = new SpannableString(fullSentence);
Pattern pattern = Pattern.compile("___");
Matcher matcher = pattern.matcher(fullSentence);
while (matcher.find()) {
    int start = matcher.start();
    int end = matcher.end();
    spannable.setSpan(new UnderlineSpan(), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}

editText.setText(spannable);
// 默认把光标定位到第一个填空位置
editText.setSelection(fullSentence.indexOf("___"));

你还可以自定义Span,比如限制每个填空的输入长度、设置输入提示等,进一步优化用户体验。

为什么之前的三TextView方案行不通?

本质原因是每个TextView都是独立的布局单元,Android布局系统会分别计算每个TextView的换行逻辑,不会把它们视为一段连续文本。当最后一个TextView内容过长时,只会在自身边界内换行,根本不可能和第一个TextView衔接——这是View的固有特性,靠调整布局参数没法解决,必须把整个句子放在同一个文本容器里。

内容的提问来源于stack exchange,提问作者Muslem Omar

火山引擎 最新活动