PopupWindow是Android中的一个弹窗,相比dialog他更加灵活,优雅,可以再任何位置显示,在开发中经常使用,尤其是在和TextView或者EditText结合使用中更加常见,最近项目做了一个自定义控件,快速搜索栏的匹配,过程中遇到这样的一个问题,当点击输入框时候会自动弹起输入法的软键盘,输入一次文字后EditText的光标就暂停闪动,一直显示在文字后面,无法输入新的内容,无法删除现有的输入内容,必须手动点击的输入框使输入法再次弹起才能输入,但是也只能输入一次,删除也只能删除一个字,光标一直显示在文字后面停止闪动,必须手动触摸才能唤起闪动,重新输入或者删除,每次输入删除只能输入一次。最后经过多次查找才解决了这个bug。最终效果如下:
一、PopupWindow的使用
1、创建View对象,用于PopupWindow内容的显示,这里显示的是listview。
ListView listView = new ListView(this);
2、创建PopupWindow对象
PopupWindow popupWindow = new PopupWindow(listView, AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.MATCH_PARENT, true);
参数1:所要设置的布局,参数2:显示布局的宽,参数3:显示布局的高,参数4:PopupWindow是否获得焦点的能力。
3、showAsDropDown(View anchor, int xoff, int yoff);
参数1:相对于此控件 参数2:相对于此控件款宽 参数3:相对于此控件高,默认显示在此控件的正下方。
//相对于父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以设置偏移或无偏移
showAtLocation(View parent, int gravity, int x, int y);
4、其他设置
PopupWindow弹出来时候默认是无法取消的额,要点击外区域取消,需要设置背景颜色,
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.WHITE));
如果有背景,则会在contentView外面包一层PopupViewContainer之后作为mPopupView,如果没有背景,则直接用contentView作为mPopupView。 而这个PopupViewContainer是一个内部私有类,它继承了FrameLayout,在其中重写了Key和Touch事件的分发处理。 设置视图可点击响应事件,如listview可以响应点击事件具有
popupWindow.setFocusable(true);
//设置为true
PopupWindow弹出后,所有的触屏和物理按键都有PopupWindows处理。其他任何事件的响应都必须发生在PopupWindow消失之后。返回键除外。
//设置为false
则PopUpWindow只是一个浮现在当前界面上的view而已,不影响当前界面的任何操作。
二、快速搜索栏的实现
现在实现快速搜索栏,当edittext的获取到输入信息时候,PopupWindow立即弹窗显示包含搜索字段的列表,显示在
listview上面 ,点击item,携带数据到相应的位置。
核心代码如下:
1、对EditText进行监听
private TextWatcher watcher = 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) {
//在此进行方法调用,获取edittext的值
String newEtText = etSearch.getText().toString().trim();
}
};
注册监听:edittext.addTextChangedListener(watcher);
2、进行字段匹配
//创建集合,存储PopupWindow要显示的内容
ArrayList<String> popwinList = new ArrayList<>();
if (list != null) { //list为所有可能被匹配到的字符串集合
for (int i = 0; i < list.size(); i++) {
if (name.contains(newEtText)) {
popwinList.add(name);
}
}
popwinShow();
}
3、对PopupWindow
private void popwinShow() {
ListView listView = new ListView(this);
listView.setAdapter(new MyAdapter(popwinList));
PopupWindow popupWindow = new PopupWindow(listView, AbsListView.LayoutParams.MATCH_PARENT,
AbsListView.LayoutParams.MATCH_PARENT, true);
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.WHITE));
popupWindow.setFocusable(false);
popupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
popupWindow.showAsDropDown(etSearch, ScreenUtils.dp2Px(18, this), ScreenUtils.dp2Px(18, this));
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
});
}
popupWindow.setFocusable(false);popupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
这两个是核心内容:
(1)设置 popupWindow.setFocusable(false); 设置popupWindow无焦点,设置为true,会导致edittext无法正常输入删除,和文章开始描述的一样,设置为false会导致popupWindow被遮盖。
(2)popupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);解决软键盘被遮挡的问题,在清单文件中设置android:windowSoftInputMode="adjustResize"可能无效。这时候需要在代码设置。