搜索自动提示

本文介绍了一种基于Android平台的自动完成搜索对话框的实现方法。通过自定义对话框和适配器,实现了带有自动补全功能的搜索界面。文章详细展示了如何处理用户输入并过滤显示结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

public class AutoCompleteSearchDialog extends Dialog {
    private Activity activity;
    ImageView accept, cancel;
    Dialog dialog;
    AutoCompleteSearchDialogListener listener;
    EditText searchview;
    private AutoLinearLayout search_container;
    private ListView searchAutoComplete;
    private SearchAutoCompleteAdapter mAdapter;

    String hint;
    String inputContent;

    private SearchItem mSelectedItem;
    private List<SearchItem> mSearchDatas = new ArrayList<SearchItem>();

    public AutoCompleteSearchDialog(Activity activity, List<SearchItem> searchDatas, String hint, AutoCompleteSearchDialogListener listener){
        super(activity, R.style.DiscoverDialog);
        this.activity=activity;
        this.dialog = this;
        this.hint = hint;
        mSearchDatas.clear();
        mSearchDatas.addAll(searchDatas);
        this.listener = listener;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dialog_auto_complete_search);

        searchview = (EditText) findViewById(R.id.dialog_input_search);
        accept = (ImageView) findViewById(R.id.dialog_input_accept);
        cancel = (ImageView) findViewById(R.id.dialog_input_cancel);
        search_container=(AutoLinearLayout)findViewById(R.id.search_container);
        searchview.setHint(hint);

        searchAutoComplete=(ListView)findViewById(R.id.lv_search);

        mAdapter=new SearchAutoCompleteAdapter(activity,mSearchDatas);
        mAdapter.setDataRecord(mSearchDatas);
        searchAutoComplete.setAdapter(mAdapter);
        searchAutoComplete.setTextFilterEnabled(true);
        searchAutoComplete.setOnItemClickListener(new ItemClick());

        accept.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                dialog.dismiss();
                inputContent=searchview.getText().toString();
                if(TextUtils.isEmpty(inputContent)){
                    mSelectedItem=null;
                }
                listener.OnAcceptClick(mSelectedItem);
            }
        });

        cancel.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                dialog.dismiss();
            }
        });

        searchview.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) {
                mAdapter.getFilter().filter(s.toString());
                search_container.setVisibility(View.VISIBLE);
//              使用用户输入的内容对ListView的列表项进行过滤,有黑框
////            lv.setFilterText(String.valueOf(s));
            }
            @Override
            public void afterTextChanged(Editable s) {
            }
        });

        setCanceledOnTouchOutside(false);
    }

    private class ItemClick implements AdapterView.OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position,
                                long id) {
            mSelectedItem=(SearchItem)mAdapter.getItem(position);
            searchview.setText(mSelectedItem.title);
            search_container.setVisibility(View.INVISIBLE);
        }
    }

    public interface AutoCompleteSearchDialogListener {
        void OnAcceptClick(SearchItem item);
    }

    public String getInput() {
        return inputContent;
    }

    public static class SearchItem{
        public String title;
        public String id;
        public String position;
        public String category;
        public int start;//记录过滤字符串的起点,只在内部使用
        public int length;//记录过滤字符串的长度,只在内部使用

        @Override
        public String toString() {
            return "--@SearchItem--[title--"+title+"--id--"+id+"--position--"+position+"--category--"+category+"--start--"+start+"--length--"+length+"--]";
        }
    }
}

public class SearchAutoCompleteAdapter extends BaseAdapter implements Filterable{
    private DataFilter mFilter;

    private Activity activity;
    private List<AutoCompleteSearchDialog.SearchItem> mDataSource;  // 这是原始的数据
    private List<AutoCompleteSearchDialog.SearchItem> mFiltData = new ArrayList<AutoCompleteSearchDialog.SearchItem>();  // 过滤之后的数据,这个数据会改变

    //设置原始数据源
    public void setDataRecord(List<AutoCompleteSearchDialog.SearchItem> list){
        mDataSource=list;
    }

    public SearchAutoCompleteAdapter(Activity activity,List<AutoCompleteSearchDialog.SearchItem> list){
        this.activity=activity;
        updateData(list);
    }

    @Override
    public int getCount() {
        return mFiltData.size();
    }
    @Override
    public Object getItem(int position) {return mFiltData.get(position);}
    @Override
    public long getItemId(int position) {
        return position;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder=null;
        if (null == convertView) {
            holder=new ViewHolder();
            convertView = View.inflate(activity, R.layout.layout_item_auto_complete_search,null);
            holder.tv= (TextView) convertView.findViewById(R.id.auto_complete_search);
            convertView.setTag(holder);
        }else{
            holder=(ViewHolder)convertView.getTag();
        }

        if(mFiltData.get(position).length>0){
            int star=mFiltData.get(position).start;
            int length=mFiltData.get(position).length;

            ForegroundColorSpan yellow = new ForegroundColorSpan(Color.rgb(255,102,0));
            SpannableString spannablestring=new SpannableString(mFiltData.get(position).title);
            spannablestring.setSpan(yellow, star, star+length,Spannable.SPAN_INCLUSIVE_INCLUSIVE);
            holder.tv.setText(spannablestring);
        }else{
            holder.tv.setText(mFiltData.get(position).title);
        }
        return convertView;
    }
    class ViewHolder{
        TextView tv;
    }
    @Override
    public Filter getFilter() {
        if (mFilter==null) {
            mFilter = new DataFilter();
        }
        return mFilter;
    }

    // 自定义Filter类
    class DataFilter extends Filter {
        @Override
        // 该方法在子线程中执行
        // 自定义过滤规则
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults();

            List<AutoCompleteSearchDialog.SearchItem> newValues = new ArrayList<AutoCompleteSearchDialog.SearchItem>();
            mFiltData.clear();
            String filterString = constraint.toString().toLowerCase();
            // 如果搜索框内容为空,就恢复原始数据
            if (TextUtils.isEmpty(filterString)) {
                for(AutoCompleteSearchDialog.SearchItem item : mDataSource){
                    item.start=0;
                    item.length=0;
                }
                newValues = mDataSource;
            } else {
                // 过滤出新数据
                for(int i=0;i<mDataSource.size();i++){
                    String str=mDataSource.get(i).title;
                    int start=str.toLowerCase().indexOf(filterString);
                    if (-1 != start) {
                        mDataSource.get(i).start=start;
                        mDataSource.get(i).length=filterString.length();
                        newValues.add(mDataSource.get(i));
                    }else{
                        mDataSource.get(i).start=0;
                        mDataSource.get(i).length=0;
                    }
                }
            }
            updateData(newValues);
            results.values = newValues;
            results.count = newValues.size();
            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint,FilterResults results) {
            updateData((List<AutoCompleteSearchDialog.SearchItem>)results.values);

            if (results.count > 0) {
                notifyDataSetChanged();  // 通知数据发生了改变
            } else {
                notifyDataSetInvalidated(); // 通知数据失效
            }
        }
    }
    //不能采用直接赋值的形式,会改变原始数据源。
    private void updateData(List<AutoCompleteSearchDialog.SearchItem> list){
        mFiltData.clear();
        mFiltData.addAll(list);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值