Android 如何定制;“芯片”;自动提示机制,用于Gmail';收件人字段? 背景

Android 如何定制;“芯片”;自动提示机制,用于Gmail';收件人字段? 背景,android,autocomplete,android-edittext,multiautocompletetextview,Android,Autocomplete,Android Edittext,Multiautocompletetextview,我一直在寻找一种与Gmail Receipents字段具有相似外观的方法,该字段允许以一种非常酷的方式自动填充项目: 内置到Android框架中并负责此操作的类称为“” 问题 MultiAutoCompleteTextView非常基本,但是它没有足够的示例、教程和库来了解如何在Gmail之类的平台上定制它 我想知道如何定制它来处理任何类型的数据,并且我将完全控制它(例如添加、删除和获取它自动完成的项目) 我试过的 我找到了实现这一目标的下一个可能的方法: 使用第三个库,如。缺点:它有很多缺陷,

我一直在寻找一种与Gmail Receipents字段具有相似外观的方法,该字段允许以一种非常酷的方式自动填充项目:

内置到Android框架中并负责此操作的类称为“”

问题 MultiAutoCompleteTextView非常基本,但是它没有足够的示例、教程和库来了解如何在Gmail之类的平台上定制它

我想知道如何定制它来处理任何类型的数据,并且我将完全控制它(例如添加、删除和获取它自动完成的项目)

我试过的 我找到了实现这一目标的下一个可能的方法:

  • 使用第三个库,如。缺点:它有很多缺陷,在某些设备上无法正常工作
  • 创建我自己的方式(如图所示)。缺点:需要很长时间,我可能需要处理与库相同的问题
  • 使用(找到的)。缺点:它实际上是不可定制的
  • 我决定使用#3(谷歌的芯片库)

    目前,获取谷歌图书馆中使用的联系人列表的代码如下:

    public List<RecipientEntry> doQuery() {
        final Cursor cursor = mContentResolver.query(mQuery.getContentUri(), mQuery.getProjection(), null, null, null);
        final LinkedHashMap<Long, List<RecipientEntry>> entryMap = new LinkedHashMap<Long, List<RecipientEntry>>();
        final List<RecipientEntry> nonAggregatedEntries = new ArrayList<RecipientEntry>();
        final Set<String> existingDestinations = new HashSet<String>();
        while (cursor.moveToNext())
            putOneEntry(new TemporaryEntry(cursor, false /* isGalContact */), true, entryMap, nonAggregatedEntries,
                    existingDestinations);
        cursor.close();
        final List<RecipientEntry> entries = new ArrayList<RecipientEntry>();
        {
            for (final Map.Entry<Long, List<RecipientEntry>> mapEntry : entryMap.entrySet()) {
                final List<RecipientEntry> entryList = mapEntry.getValue();
                for (final RecipientEntry recipientEntry : entryList)
                    entries.add(recipientEntry);
            }
            for (final RecipientEntry entry : nonAggregatedEntries)
                entries.add(entry);
        }
        return entries;
    }
    
    公共列表doQuery(){
    最终游标Cursor=mContentResolver.query(mQuery.getContentUri(),mQuery.getProjection(),null,null);
    final LinkedHashMap entryMap=新LinkedHashMap();
    最终列表非聚集项=新ArrayList();
    final Set existingDestinations=新HashSet();
    while(cursor.moveToNext())
    putOneEntry(新的临时条目(游标,false/*isGalContact*/),true,entryMap,非聚集条目,
    现有目的地);
    cursor.close();
    最终列表条目=新的ArrayList();
    {
    对于(最终映射.Entry映射条目:entryMap.entrySet()){
    最终列表entryList=mapEntry.getValue();
    for(最终收件人条目收件人条目:条目列表)
    条目。添加(recipientEntry);
    }
    对于(最终收件人条目:非汇总条目)
    条目。添加(条目);
    }
    返回条目;
    }
    
    它工作正常,但我在添加和删除项目时遇到困难

    我认为获取项目是通过调用“getContactID”来使用的,但是关于修改芯片中的项目,很难找到

    例如,我尝试向“submitItemPosition”添加一个类似的函数,它似乎添加了一个从适配器中找到的新实体。它确实添加了,但是芯片本身没有显示触点的显示名称

    问题 经过深思熟虑,我决定使用谷歌的代码

    遗憾的是,正如我所写的,视图及其类与它的使用紧密相关

  • 如何将视图解耦并使其更加可定制?我如何让它使用任何类型的数据,而不仅仅是谷歌所做的

  • 如何获取输入的项目(成为“芯片”),以及如何从外部删除或添加项目


  • 我已成功添加添加收件人的功能。要记住的唯一一件事是仅在视图获得其大小后调用它(如何执行此操作的示例):

    删除时:

    /** removes a chip of a recipient from the view */
    public void removeRecipient(final RecipientEntry entry) {
        final DrawableRecipientChip[] chips = getSpannable().getSpans(0, getText().length(),
                DrawableRecipientChip.class);
        final List<DrawableRecipientChip> chipsToRemove = new ArrayList<DrawableRecipientChip>();
        for (final DrawableRecipientChip chip : chips)
            if (chip.getDataId() == entry.getDataId())
                chipsToRemove.add(chip);
        for (final DrawableRecipientChip chip : chipsToRemove)
            removeChip(chip);
    }
    
    /**从视图中删除收件人的芯片*/
    公共作废清除人(最终接收人条目){
    final DrawableRecipientChip[]chips=GetSpanable().getSpans(0,getText().length(),
    DrawableRecipientChip.class);
    最终列表chipsToRemove=new ArrayList();
    用于(最终可拉拔接收器芯片:芯片)
    if(chip.getDataId()==entry.getDataId())
    chipsToRemove.add(芯片);
    用于(最终可拉伸接收器芯片:chipsToRemove)
    去除芯片;
    }
    
    如前所述,要获取视图中当前的ContactID列表,请使用“getContactID()。另一种选择是:

    /** returns a collection of all of the chips' items. key is the contact id, and the value is the recipient itself */
    public Map<Long, RecipientEntry> getChosenRecipients() {
        final Map<Long, RecipientEntry> result = new HashMap<Long, RecipientEntry>();
        final DrawableRecipientChip[] chips = getSortedRecipients();
        if (chips != null)
            for (final DrawableRecipientChip chip : chips) {
                // if(result.)
                final long contactId = chip.getContactId();
                if (!result.containsKey(contactId))
                    result.put(contactId, chip.getEntry());
            }
        return result;
    }
    
    /**返回所有芯片项目的集合。键是联系人id,值是收件人本身*/
    公共映射getChosenRecipients(){
    最终映射结果=新HashMap();
    最终DrawableRecipientChip[]chips=getSortedRecipients();
    如果(芯片数!=null)
    用于(最终可拉拔接收器芯片:芯片){
    //如果(结果)
    final long contactId=chip.getContactId();
    如果(!result.containsKey(contactId))
    result.put(contactId,chip.getEntry());
    }
    返回结果;
    }
    
    也许我应该在Github上发布代码

    我现在唯一怀念的是一个好的芯片监听器:当一个芯片被添加、移除和替换时。在大多数情况下,我都能检测到它,但当用户按下backspace并移除芯片时,我就无法检测到


    编辑:还添加了侦听器。现在我在搜索联系人时发现了一个bug。它似乎在搜索普通的英文字母,就好像它们是电话号码一样


    编辑:我决定在GitHub上放置一个示例和一个库。希望很快能用更多有用的功能来更新它


    我真的很乐意为代码做出任何贡献。

    此库似乎允许您配置它搜索的内容,同时也匹配材质设计外观。它似乎也是基于谷歌的芯片库。我在调查类似问题时碰巧发现了它


    这可能会有所帮助you@HardikTrivedi事实上,我也读过,没有找到关于如何管理所选项目(包括添加、删除和查询)的答案。我想就像我尝试过的库一样,这个库在一些设备上也有bug。我也很喜欢Google的库的样子,所以我想用它作为基本代码。唯一的问题是谷歌把它变得非常复杂,很难修改,也很难阅读。@androiddeveloper查看我修改的要点:@pskink目前我使用的是
    /** returns a collection of all of the chips' items. key is the contact id, and the value is the recipient itself */
    public Map<Long, RecipientEntry> getChosenRecipients() {
        final Map<Long, RecipientEntry> result = new HashMap<Long, RecipientEntry>();
        final DrawableRecipientChip[] chips = getSortedRecipients();
        if (chips != null)
            for (final DrawableRecipientChip chip : chips) {
                // if(result.)
                final long contactId = chip.getContactId();
                if (!result.containsKey(contactId))
                    result.put(contactId, chip.getEntry());
            }
        return result;
    }