如何在Android输入框中添加Material Components库的Chips组件?
实现类似Gmail的无前置图标输入Chips(Material Components版)
我之前也遇到过完全一样的需求,结合Material Components库,有两种靠谱的实现方式,帮你解决这个问题:
方案一:ChipGroup + 输入框组合(最贴近Gmail体验)
这是官方推荐的实现思路,逻辑清晰,用户输入后按回车/完成键生成Chip,操作流畅直观。
步骤1:导入Material Components依赖
首先确保你的项目替换掉旧的AppCompat Design库,使用最新的Material Components依赖:
implementation 'com.google.android.material:material:1.9.0' // 可替换为最新稳定版
步骤2:编写布局文件
用TextInputLayout包裹输入框,下方搭配ChipGroup承载生成的Chip:
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="16dp"> <com.google.android.material.textfield.TextInputLayout android:id="@+id/tagInputLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="输入标签"> <com.google.android.material.textfield.TextInputEditText android:id="@+id/tagEditText" android:layout_width="match_parent" android:layout_height="wrap_content" android:imeOptions="actionDone"/> </com.google.android.material.textfield.TextInputLayout> <com.google.android.material.chip.ChipGroup android:id="@+id/tagChipGroup" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" app:chipSpacing="8dp"/> </LinearLayout>
步骤3:处理输入逻辑
给输入框添加编辑器监听,当用户按下完成键时,生成无前置图标的Chip并添加到ChipGroup:
// 初始化控件 TextInputEditText tagEditText = findViewById(R.id.tagEditText); ChipGroup tagChipGroup = findViewById(R.id.tagChipGroup); // 设置完成键监听 tagEditText.setOnEditorActionListener((v, actionId, event) -> { if (actionId == EditorInfo.IME_ACTION_DONE) { String inputText = v.getText().toString().trim(); if (!inputText.isEmpty()) { createTagChip(inputText, tagChipGroup); v.setText(""); // 清空输入框 // 隐藏软键盘(可选) InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } return true; } return false; }); // 创建无前置图标的Chip方法 private void createTagChip(String text, ChipGroup parent) { Chip chip = new Chip(this); chip.setText(text); chip.setCloseIconVisible(true); // 显示关闭按钮 chip.setChipIcon(null); // 移除前置图标 chip.setChipBackgroundColorResource(R.color.material_blue_grey_100); // 自定义背景色(可选) // 点击关闭按钮移除Chip chip.setOnCloseIconClickListener(v -> parent.removeView(chip)); parent.addView(chip); }
方案二:将Chip嵌入EditText(Span方式)
如果你需要把Chip直接和输入文本混排在输入框内,可以用ChipDrawable配合ImageSpan实现,你之前的问题大概率是没正确设置Drawable的边界或占位字符:
核心代码实现
TextInputEditText editText = findViewById(R.id.tagEditText); // 创建无前置图标的ChipDrawable ChipDrawable chipDrawable = ChipDrawable.createFromAttributes( this, null, 0, R.style.Widget_MaterialComponents_Chip_Entry // 使用Entry样式的Chip ); chipDrawable.setText("我的标签"); chipDrawable.setCloseIconVisible(true); chipDrawable.setChipIcon(null); // 移除前置图标 // 关键:设置ChipDrawable的显示边界,否则Span会显示为空 chipDrawable.setBounds(0, 0, chipDrawable.getIntrinsicWidth(), chipDrawable.getIntrinsicHeight()); // 给Chip添加关闭事件 chipDrawable.setOnCloseIconClickListener(v -> { Editable editable = editText.getText(); int spanStart = editable.getSpanStart(chipDrawable); int spanEnd = editable.getSpanEnd(chipDrawable); if (spanStart != -1 && spanEnd != -1) { editable.removeSpan(chipDrawable); editable.delete(spanStart, spanEnd); // 删除占位字符 } }); // 将ChipDrawable转为Span插入到EditText Editable editable = editText.getText(); int cursorPos = editText.getSelectionStart(); // 插入一个空格作为Span的占位(必须,否则Span没有显示位置) editable.insert(cursorPos, " "); ImageSpan chipSpan = new ImageSpan(chipDrawable, ImageSpan.ALIGN_BASELINE); editable.setSpan(chipSpan, cursorPos, cursorPos + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // 移动光标到Chip后方,方便继续输入 editText.setSelection(cursorPos + 1);
重要注意事项
- 主题适配:你的App主题必须继承自Material Components主题,比如
Theme.MaterialComponents.Light.DarkActionBar,否则Chip组件样式会出现异常。 - 迁移提示:如果还在使用旧的
android.support.design库,建议完全迁移到com.google.android.material,避免兼容性问题。 - 自动扩展:如果需要输入时的自动提示功能,可以替换
TextInputEditText为MaterialAutoCompleteTextView,配合ArrayAdapter实现标签建议。
内容的提问来源于stack exchange,提问作者IDmikael
相关产品推荐
相关产品推荐

