自定义 AutoCompleteTextView 行为

发布于 2024-12-29 10:48:40 字数 189 浏览 2 评论 0原文

开箱即用的 AutoCompleteTextView 小部件似乎无法匹配列表值中间的输入字符串 - 匹配始终在开头进行;例如,输入“ar”匹配“argentina”,但不匹配“hungary”。

如何搜索单词中间的文本?谁能给我一个主意吗?

提前致谢 !

Out of the box, the AutoCompleteTextView widget does not seem to be able to match the input string in the middle of a list value - the matches are always made at the beginning; e.g., entering "ar" matches "argentina", but not "hungary".

How can I search for the text in the middle of the word ? Can anyone give me an idea ?

Thanks in advance !

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

不爱素颜 2025-01-05 10:48:41
public class AutoCompleteAdapter <T> extends ArrayAdapter<T> implements Filterable {
    private List <T> listObjects;
    List<T> suggestions = new ArrayList<>();
    private Context context;
    public AutoCompleteAdapter(Context context, List<T> listObjects) {
        super(context, R.layout.list_item_simple, listObjects);
        this.listObjects = new ArrayList<>(listObjects);
        this.context = context;
    }
    private Filter mFilter = new Filter(){
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults filterResults = new FilterResults();
            if(constraint != null) {
            suggestions.clear();
                for(T object : listObjects){  
                    if(object.toString().toLowerCase().contains(constraint.toString().toLowerCase())){                        suggestions.add(object);
                }
            }

            filterResults.values = suggestions;
            filterResults.count = suggestions.size();
        }
        return filterResults;
    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        if(results == null){
            return;
        }
        List<T> filteredList = (List<T>) results.values;
        if(results.count > 0) {
            clear();
            for (T filteredObject : filteredList) {
                add(filteredObject);
            }
            notifyDataSetChanged();
        }
    }
};
@Override
public Filter getFilter() {
    return mFilter;
}
private static class ViewHolder {
    TextView title;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    Object listObject = getItem(position);
    final ViewHolder viewHolder; // view lookup cache stored in tag
    if (convertView == null) {
        viewHolder = new ViewHolder();
        LayoutInflater inflater = LayoutInflater.from(getContext());
        convertView = inflater.inflate(R.layout.list_item_simple, parent, false);
        viewHolder.title = (TextView) convertView.findViewById(R.id.title);
        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }
    viewHolder.title.setText(listObject.toString());
    return convertView;
}

}

public class AutoCompleteAdapter <T> extends ArrayAdapter<T> implements Filterable {
    private List <T> listObjects;
    List<T> suggestions = new ArrayList<>();
    private Context context;
    public AutoCompleteAdapter(Context context, List<T> listObjects) {
        super(context, R.layout.list_item_simple, listObjects);
        this.listObjects = new ArrayList<>(listObjects);
        this.context = context;
    }
    private Filter mFilter = new Filter(){
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults filterResults = new FilterResults();
            if(constraint != null) {
            suggestions.clear();
                for(T object : listObjects){  
                    if(object.toString().toLowerCase().contains(constraint.toString().toLowerCase())){                        suggestions.add(object);
                }
            }

            filterResults.values = suggestions;
            filterResults.count = suggestions.size();
        }
        return filterResults;
    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        if(results == null){
            return;
        }
        List<T> filteredList = (List<T>) results.values;
        if(results.count > 0) {
            clear();
            for (T filteredObject : filteredList) {
                add(filteredObject);
            }
            notifyDataSetChanged();
        }
    }
};
@Override
public Filter getFilter() {
    return mFilter;
}
private static class ViewHolder {
    TextView title;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    Object listObject = getItem(position);
    final ViewHolder viewHolder; // view lookup cache stored in tag
    if (convertView == null) {
        viewHolder = new ViewHolder();
        LayoutInflater inflater = LayoutInflater.from(getContext());
        convertView = inflater.inflate(R.layout.list_item_simple, parent, false);
        viewHolder.title = (TextView) convertView.findViewById(R.id.title);
        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }
    viewHolder.title.setText(listObject.toString());
    return convertView;
}

}

夏有森光若流苏 2025-01-05 10:48:41

我的建议是将字符串解析为字符数组。
然后迭代每个字符,直到找到字符串。

例如,假设您的搜索想要返回所有包含“ate”的单词,并且单词列表是...

状态
特征
斥责
晚了

你的算法应该是这样的

获取字符串并将其解析为字符数组
循环遍历数组并找到第一个“正确字符”(在我们的示例中为“a”)
找到该字符后,检查下一个字符,继续检查每个字符是否匹配,直到搜索的值完成。如果该字符不匹配,则退出数组迭代并转到下一个单词。

My advice would be to parse the string into a character array.
Then iterate each character until the string is found.

For example lets say your search wanted to return all words with "ate" in them and the word list was...

state
trait
berate
late

Your algorithm should go something like this

Take the string and parse it into a character array
Loop through the array and find the first "correct character" (in our example its 'a')
Once that character is found check the next character, keep checking each character for a match until the value being searched for is complete. If the character is not a match exit the array iteration and go to the next word.

难如初 2025-01-05 10:48:40

您需要编写一个自定义 Filter类并实现 performFiltering 方法。此方法采用 CharSequence 参数,您可以使用该参数执行所需的任何字符串操作,以便从数据集中生成匹配列表(在您的情况下,您可以使用 String.contains 而不是 String.startsWith)。 performFiltering 函数不在 UI 线程上运行。

然后,您将匹配列表作为 FilterResults 返回 对象,其中包含一个 Object values(您的匹配列表,可能是一个 ArrayList)和一个 int count 这是你的大小匹配列表。

最后,实现 publishResults 回调方法,一旦工作线程生成匹配列表,该方法就会返回,允许您调用 notifyDataSetChanged AutoCompleteTextView 的适配器,以便它可以显示结果。

You would need to write a custom Filter class and implement the performFiltering method yourself. This method takes a CharSequence argument, which you can use to perform whatever String operations you need in order to generate a list of matches from your dataset (in your case, you could use String.contains instead of String.startsWith). The performFiltering function is not run on the UI thread.

You then return your list of matches as a FilterResults object, which contains an Object values (your list of matches, probably an ArrayList) and an int count which is the size of your list of matches.

Finally, implement the publishResults callback method, which returns once the worker thread has generated the list of matches, allowing you to call notifyDataSetChanged on your AutoCompleteTextView's adapter so that it can display the results.

樱桃奶球 2025-01-05 10:48:40

老问题,但仍然相关。按照其他几个问题的指导,使用可过滤实现了自定义适配器。我制作了一个简单的通用适配器,可以使用 contains 进行搜索。关于它的快速说明:

我正在使用 butterknife,但是使用 findviewbyid 可以轻松完成 viewHolder。

布局 R.layout.list_item_simple 是带有文本视图 R.id.text_view_simple 的简单布局。

该对象需要一个要进行比较的 toString。

public class SimpleContainsAutocompleteAdapter <T> extends ArrayAdapter<T> implements Filterable {
    private List <T> listObjects;
    List<T> suggestions = new ArrayList<>();
    private int resource;

    private Filter mFilter = new Filter(){
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults filterResults = new FilterResults();

            if(constraint != null) {
                suggestions.clear();
                for(T object : listObjects){
                    if(object.toString().toLowerCase().contains(constraint.toString().toLowerCase())){
                        suggestions.add(object);
                    }
                }

                filterResults.values = suggestions;
                filterResults.count = suggestions.size();
            }

            return filterResults;
        }

        @Override
        protected void publishResults(CharSequence contraint, FilterResults results) {
            if(results == null){
                return;
            }

            List<T> filteredList = (List<T>) results.values;
            if(results.count > 0) {
                clear();
                for (T filteredObject : filteredList) {
                    add(filteredObject);
                }
                notifyDataSetChanged();
            }
        }
    };

    public SimpleContainsAutocompleteAdapter(Context context, List<T> listObjects) {
        super(context, R.layout.list_item_simple, listObjects);
        this.listObjects = new ArrayList<>(listObjects);
        this.resource = R.layout.list_item_simple;
    }

    @Override
    public Filter getFilter() {
        return mFilter;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Object listObject = getItem(position);
        viewHolder holder;
        if(convertView != null) {
            holder = (viewHolder) convertView.getTag();
        }else{
            convertView = LayoutInflater.from(getContext()).inflate(resource, parent, false);
            holder = new viewHolder(convertView);
            convertView.setTag(holder);
        }

        holder.name.setText(listObject.toString());

        return convertView;
    }


    static class viewHolder {
        @InjectView(R.id.text_view_simple) TextView name;

        public viewHolder(View view) {
            ButterKnife.inject(this, view);
        }
    }
}

Old question, but still relevant. Following the guidance of a few other questions implemented a custom adapter using filterable. I made a simple generic adapter that searches with contains. Quick notes on it:

I'm using butterknife, but easy to do the viewHolder with findviewbyid.

The layout R.layout.list_item_simple is a simple layout with the textview R.id.text_view_simple.

The object needs a toString that will be compared.

public class SimpleContainsAutocompleteAdapter <T> extends ArrayAdapter<T> implements Filterable {
    private List <T> listObjects;
    List<T> suggestions = new ArrayList<>();
    private int resource;

    private Filter mFilter = new Filter(){
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults filterResults = new FilterResults();

            if(constraint != null) {
                suggestions.clear();
                for(T object : listObjects){
                    if(object.toString().toLowerCase().contains(constraint.toString().toLowerCase())){
                        suggestions.add(object);
                    }
                }

                filterResults.values = suggestions;
                filterResults.count = suggestions.size();
            }

            return filterResults;
        }

        @Override
        protected void publishResults(CharSequence contraint, FilterResults results) {
            if(results == null){
                return;
            }

            List<T> filteredList = (List<T>) results.values;
            if(results.count > 0) {
                clear();
                for (T filteredObject : filteredList) {
                    add(filteredObject);
                }
                notifyDataSetChanged();
            }
        }
    };

    public SimpleContainsAutocompleteAdapter(Context context, List<T> listObjects) {
        super(context, R.layout.list_item_simple, listObjects);
        this.listObjects = new ArrayList<>(listObjects);
        this.resource = R.layout.list_item_simple;
    }

    @Override
    public Filter getFilter() {
        return mFilter;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Object listObject = getItem(position);
        viewHolder holder;
        if(convertView != null) {
            holder = (viewHolder) convertView.getTag();
        }else{
            convertView = LayoutInflater.from(getContext()).inflate(resource, parent, false);
            holder = new viewHolder(convertView);
            convertView.setTag(holder);
        }

        holder.name.setText(listObject.toString());

        return convertView;
    }


    static class viewHolder {
        @InjectView(R.id.text_view_simple) TextView name;

        public viewHolder(View view) {
            ButterKnife.inject(this, view);
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文