如何在 android 中使用自动完成功能将 Material Design Chip 添加到输入字段?

How to add Material Design Chips to input field using autocomplete in android?

我正在尝试使用 AutoCompleteTextView 实现 Material Design Chips,以便在用户单击自动完成建议(如 Gmail 收件人信息条)时在输入字段中添加联系人信息条。

可以在 Material Design Website 上看到所需的行为。

我决定在我的项目中从头开始实现 Chips 和 AutoCompleteTextView,而无需外部库。但是,我没有找到任何说明如何执行此操作的指南。

我尝试创建一个独立的 ChipDrawable,然后将其添加到 AutoCompleteTextView,如下所示:

布局

<chip
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:chipIcon="@drawable/ic_avatar_circle_24"
    android:text="@string/contact_name"/>

Java代码

ChipDrawable chip = ChipDrawable.createFromResource(getContext(), R.xml.standalone_chip);

chip.setBounds(0, 0, chip.getIntrinsicWidth(), chip.getIntrinsicHeight());
DrawableMarginSpan span = new DrawableMarginSpan(chip, 25);

Editable text = editText.getText();
text.setSpan(span, 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

不幸的是,它没有按预期工作。首先,我只能在 Chip 上添加更多内容。此外,芯片的样式很奇怪(高度太大,不居中)。

那么如何使用 Material Design Input Chips 创建像 Gmail 或 SMS 应用程序中那样的 Contact Chips?也许有人知道一些实施指南?

在此先致谢,非常感谢您的帮助!

如果您正在寻找与 Gmail 联系人编辑框一样的收件人编辑框,这里有一个实施视频应该对您有所帮助:

How to implement Chips with AutoCompleteTextView for Android

假设您有联系人数据 class,请按以下步骤操作:

MultiAutoCompleteTextView 设置

MultiAutoCompleteTextView contactAutoCompleteTextView = findViewById(R.id.recipient_auto_complete_text_view);
List<Contact> contacts = new ArrayList<Contact>() {{
    add(new Contact("Adam Ford", R.drawable.adam_ford));
    add(new Contact("Adele McCormick", R.drawable.adele_mccormick));
    add(new Contact("Alexandra Hollander", R.drawable.alexandra_hollander));
    add(new Contact("Alice Paul", R.drawable.alice_paul));
    add(new Contact("Arthur Roch", R.drawable.arthur_roch));
}};

contactAutoCompleteTextView.setAdapter(new ContactAdapter(this,
        R.layout.contact_layout, contacts));
contactAutoCompleteTextView.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer());
// Minimum number of characters the user has to type before the drop-down list is shown
contactAutoCompleteTextView.setThreshold(1);
contactAutoCompleteTextView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
        Contact selectedContact = (Contact) adapterView.getItemAtPosition(i);
        createRecipientChip(selectedContact);
    }
});

芯片资源

<chip style="@style/Widget.MaterialComponents.Chip.Action"/>

芯片创建

private void createRecipientChip(Contact selectedContact) {
    ChipDrawable chip = ChipDrawable.createFromResource(this, R.xml.standalone_chip);
    CenteredImageSpan span = new CenteredImageSpan(chip, 40f, 40f);
    int cursorPosition = contactAutoCompleteTextView.getSelectionStart();
    int spanLength = selectedContact.getName().length() + 2;
    Editable text = contactAutoCompleteTextView.getText();
    chip.setChipIcon(ContextCompat.getDrawable(MainActivity.this,
        selectedContact.getAvatarResource()));
    chip.setText(selectedContact.getName());
    chip.setBounds(0, 0, chip.getIntrinsicWidth(), chip.getIntrinsicHeight());
    text.setSpan(span, cursorPosition - spanLength, cursorPosition, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}

CenteredImageSpan 是一个自定义的 ImageSpan,它使可绘制对象垂直居中。它还允许我们设置芯片填充。 link.

中提供了完整的代码

在此示例中,可以在您键入时从建议列表中选择联系人。然后,创建联系人 Chip(具有名称和头像)以替换搜索查询。至于多个联系人处理,您正在寻找 MultiAutoCompleteTextView。视频中有描述。

希望对您有所帮助。