Android 根据首字或字母进行模糊搜索

Android 应用中很多地方需要用到根据首字,或者拼音等进行模糊搜索,如下图,输入拼音就会显示模糊搜索的结果,一般需要模糊查询的都是网络数据,很少是本地写死的,
Android 根据首字或字母进行模糊搜索_第1张图片

AutoCompleteTextView

这个Android 控件相信很多人都没怎么用过,我也是要做这种查询结果的时候,才发现有这个控件的(可能我太孤陋寡闻),哈哈哈。

AutoCompleteTextView 几个常用属性:
"match_parent"
            android:layout_height="wrap_content"
            android:completionThreshold="1"                    //设置用户至少输入几个字符才会显示
            android:dropDownHeight="200dp"                     //设置下拉菜单的高度
            android:dropDownWidth="180dp"                      //设置下拉菜单的宽度
            android:gravity="center"
            android:textSize="15sp" />

我这里只用到上面三个,其实还有很多个

android:popupBackground     //设置下拉菜单的背景
dropDownSelector            //设置选中的背景颜色
.......

这里就不全部写出来了,有需要百度一下就有了

实例:

这里以查询的结果是网络请求的为例,因为我这里是后台已经把根据拼音查找汉字的做好了,我就不用再转换了,如果需要转换的,找一下转换的工具类就可以了。

        //监听输入框的变化
        autoView.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) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                cust_id_code = String.valueOf(s);
                cust_id_View.setText("");
                //监听输入框,已输入就去查询
                if (cust_id_code != null) {
                    //判断是否有网络
                    if (!isNetworkAvailable(ScanOrderActivity.this)) {
                        UtilToast.showToast(ScanOrderActivity.this, "请检查您的网络");
                    } else {
                        iniData();
                    }
                }
            }
        });

在这里监听输入框,当有用户输入数据时,先进行网络判断,如果有网络就进行请求。
请求成功有数据后就可以给 AutoCompleteTextView 设置适配器了,适配器跟 Spinner 下拉框的适配器差不多

 searchAdapter = new ArrayAdapter(ScanOrderActivity.this, android.R.layout.simple_list_item_1, array);
 autoView.setAdapter(searchAdapter);

网络请求回来的数据通过解析,我这边解析生成的是 List ,而适配器要的是 String [ ];所以要转换一下,

String [] array = arrayList.toArray(new String[arrayList.size()])

注意:
记得在主线程 更新Ui,如果是Rxjava+Retrofit做的网络请求,直接设置,和刷新就可了,如果是其他的需要切换到主线程,我这边是用 Handler,如果不懂 Handler 可以参考我这一篇Handler 的解析 https://www.jianshu.com/p/cb0364856349

   @Override
            public void onResponse(Call call, Response response) throws IOException {
                cust_name.clear();
                Gson gson = new Gson();
                scanSearchModel = gson.fromJson(response.body().string(), ScanSearchModel.class);
                for (int i = 0; i < scanSearchModel.getData().size(); i++) {
                   arrayList.add(scanSearchModel.getData().get(i).getCust_name());
                }
                //array转String[]
                array =arrayList.toArray(new String[arrayList.size()]);
                Message message = new Message();
                message.what = UPDATA;
                handler.sendMessage(message);
            }

Hnadler

private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case UPDATA:
                    if (array != null) {
                        searchAdapter = new ArrayAdapter(ScanOrderActivity.this, android.R.layout.simple_list_item_1, array);
                        autoView.setAdapter(searchAdapter);
                        searchAdapter.notifyDataSetChanged();
                    }
                    break;
                default:
                    break;
            }
        }
    };

还需要记得当当前Activity销毁时,移除Handler,或者把Handler声明成 static +弱引用,然后使用否则会导致非静态内部类隐式持有外部类的引用的内存泄漏,这里为了方便就用了移除

 @Override
    protected void onDestroy() {
        super.onDestroy();
        handler.removeMessages(UPDATA);
    }

你可能感兴趣的:(Android)