Android开发:如何将EditText内容与TextView字符串资源拼接显示?
Android中实现EditText内容追加到TextView文本的正确方式
问题背景
我有如下布局代码:
<EditText android:id="@+id/et_name" android:layout_width="match_parent" android:layout_height="48dp" android:layout_margin="20dp" android:hint="@string/str_name" /> <TextView android:id="@+id/tvSentence" android:layout_width="match_parent" android:layout_height="48dp" android:text="@string/str_hello1"/>
想把et_name的输入内容追加到@string/str_hello1的文本后面,但尝试的几种XML写法都报错“unexpected text”:
- 写法一:
<TextView android:layout_width="match_parent" android:layout_height="48dp" android:text="@string/str_hello1" + "@+id/et_name" />
- 写法二:
android:text="@string/str_hello1" + et_name
- 写法三:
android:text="@string/str_hello1" + "et_name"
为什么之前的写法不行?
XML布局是静态的界面描述文件,不支持在属性中直接使用+做动态文本拼接,也无法直接引用控件的实时输入内容,所以这些写法都是语法错误,必然会报错。
可行解决方案
方案1:代码中监听输入并动态更新(最通用)
在Activity/Fragment中获取控件实例,监听EditText的输入变化,实时拼接文本并更新TextView:
Kotlin示例:
val etName = findViewById<EditText>(R.id.et_name) val tvSentence = findViewById<TextView>(R.id.tvSentence) val helloBaseText = getString(R.string.str_hello1) // 监听输入内容变化 etName.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { // 拼接基础文本和输入内容 tvSentence.text = "$helloBaseText${s ?: ""}" } override fun afterTextChanged(s: Editable?) {} })
Java示例:
EditText etName = findViewById(R.id.et_name); TextView tvSentence = findViewById(R.id.tvSentence); String helloBaseText = getString(R.string.str_hello1); etName.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @Override public void onTextChanged(CharSequence s, int start, int before, int count) { tvSentence.setText(helloBaseText + (s != null ? s : "")); } @Override public void afterTextChanged(Editable s) {} });
方案2:用DataBinding实现(MVVM架构适配)
如果项目使用DataBinding,可以通过绑定表达式实现动态拼接:
- 先在布局根节点开启DataBinding,并定义变量:
<layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="helloBaseText" type="String" /> <variable name="userName" type="String" /> </data> <EditText android:id="@+id/et_name" android:layout_width="match_parent" android:layout_height="48dp" android:layout_margin="20dp" android:hint="@string/str_name" android:text="@={userName}" /> <!-- 双向绑定输入内容 --> <TextView android:id="@+id/tvSentence" android:layout_width="match_parent" android:layout_height="48dp" android:text="@{helloBaseText + userName}" /> <!-- 直接拼接变量 --> </layout>
- 在Activity中初始化绑定数据:
Kotlin示例:
val binding = DataBindingUtil.setContentView<YourLayoutBinding>(this, R.layout.your_layout) binding.helloBaseText = getString(R.string.str_hello1) binding.userName = "" // 初始化输入内容
Java示例:
YourLayoutBinding binding = DataBindingUtil.setContentView(this, R.layout.your_layout); binding.setHelloBaseText(getString(R.string.str_hello1)); binding.setUserName("");
方案3:字符串资源占位符(非实时更新场景)
如果不需要实时监听输入,只需要在特定时机(比如点击按钮)拼接,可以用字符串占位符:
- 在
strings.xml中定义带占位符的字符串:
<string name="hello_with_name">%1$s%2$s</string>
- 在代码中触发拼接:
Kotlin示例:
// 比如点击按钮时更新 btnUpdate.setOnClickListener { val helloBase = getString(R.string.str_hello1) val userName = etName.text.toString() tvSentence.text = getString(R.string.hello_with_name, helloBase, userName) }
Java示例:
btnUpdate.setOnClickListener(v -> { String helloBase = getString(R.string.str_hello1); String userName = etName.getText().toString(); tvSentence.setText(getString(R.string.hello_with_name, helloBase, userName)); });
内容的提问来源于stack exchange,提问作者getoffmylap
相关产品推荐
相关产品推荐

