Android 应用中很多地方需要用到根据首字,或者拼音等进行模糊搜索,如下图,输入拼音就会显示模糊搜索的结果,一般需要模糊查询的都是网络数据,很少是本地写死的,
AutoCompleteTextView
这个Android 控件相信很多人都没怎么用过,我也是要做这种查询结果的时候,才发现有这个控件的(可能我太孤陋寡闻),哈哈哈。
AutoCompleteTextView 几个常用属性:
<AutoCompleteTextView
android:layout_width="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<String>(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<String>(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);
}