Android EditText+ListPopupWindow实现可编辑的下拉列表
📖1. 可编辑的下拉列表
效果图:
✅步骤一:准备视图
EditText视图:
<EditText
android:id="@+id/edit_text"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="35dp"
android:layout_marginLeft="0dp"
android:layout_marginRight="10dp"
android:background="@drawable/shape_edit2"
android:inputType="text"
android:textColor="@color/black"
android:hint="输入内容"
android:textSize="16sp" />
shape_edit2
形状文件
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 指定了形状内部的填充颜色 -->
<solid android:color="#ffffff" />
<!-- 指定了形状轮廓的粗细与颜色 -->
<stroke
android:width="1dp"
android:color="@color/black_gray" />
<!-- 指定了形状四个圆角的半径 -->
<corners android:radius="0dp" />
<!-- 指定了形状四个方向的间距 -->
<padding
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp" />
</shape>
✅步骤二:封装显示方法
private ListPopupWindow listPopupWindow;//ListPopupWindow
private ArrayAdapter<String> adapter;//数组适配
private List<String> suggestions;//下拉数据列表
private static final int MAX_VISIBLE_ITEMS = 5;//最大显示数据行
//显示下拉列表方法
private void showSuggestions(String query) {
if (listPopupWindow == null) {
// 初始化 ListPopupWindow
listPopupWindow = new ListPopupWindow(getActivity());
// 初始化适配器
adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1, new ArrayList<>());
listPopupWindow.setAdapter(adapter);
listPopupWindow.setAnchorView(edit_text);
listPopupWindow.setModal(false);
// 设置下拉列表项点击事件
listPopupWindow.setOnItemClickListener((parent, view, position, id) -> {
String selectedItem = adapter.getItem(position);
if (selectedItem != null) {
// 设置编辑框内容为选中项,并将光标移至文本末尾
edit_text.setText(selectedItem);
edit_text.setSelection(selectedItem.length());
}
// 隐藏下拉列表
listPopupWindow.dismiss();
});
}
// 过滤并设置下拉列表数据
List<String> filteredSuggestions = new ArrayList<>();
for (String suggestion : suggestions) {
if (suggestion.toLowerCase().contains(query.toLowerCase())) {
filteredSuggestions.add(suggestion);
}
}
// 更新适配器数据
adapter.clear();
adapter.addAll(filteredSuggestions);
// 如果过滤后的建议列表不为空,则显示下拉列表
if (!filteredSuggestions.isEmpty()) {
// 获取每行的高度
int itemHeight = getResources().getDimensionPixelSize(android.R.dimen.app_icon_size);
// 动态计算ListPopupWindow 的高度,最大高度=MAX_VISIBLE_ITEMS
int height = Math.min(filteredSuggestions.size(), MAX_VISIBLE_ITEMS) * itemHeight;
// 设置 ListPopupWindow 的高度
listPopupWindow.setHeight(height);
// 显示下拉列表
listPopupWindow.show();
} else {
// 隐藏下拉列表
listPopupWindow.dismiss();
}
}
✅步骤三:获取视图并监听
1.获取输入框
EditText edit_text = findViewById(R.id.edit_text);//输入框
2.生成下拉数据(这里的数据可换成真实的数据库数据),监听文本变化
//生成数据
suggestions = new ArrayList<>();
suggestions.add("item1");
suggestions.add("item2");
suggestions.add("item3");
suggestions.add("item4");
//监听文本变化
edit_text.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// No-op
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
showSuggestions(s.toString());//调取显示下拉列表方法
}
@Override
public void afterTextChanged(Editable s) {
// No-op
}
});
至此实现完成。
📖2. 扩展上下箭头
效果图:
✅步骤一:准备上下箭头icon图标
上箭头item_icon_up.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:width="30dp"
android:height="30dp"
android:drawable="@drawable/icon_up_selected" />
</layer-list>
下箭头item_icon_down.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:width="30dp"
android:height="30dp"
android:drawable="@drawable/icon_down_selected" />
</layer-list>
里面的图片可直接再阿里巴巴图标库搜索"上拉"、"下拉"即可
✅步骤二:drawableRight属性
编辑框添加drawableRight
属性,EditText可以添加上下左右图片资源,我们添加右边即可。
<EditText
android:id="@+id/edit_text"
android:layout_width="0dp"
android:layout_height="35dp"
android:layout_marginLeft="0dp"
android:layout_marginRight="10dp"
android:layout_weight="1"
android:background="@drawable/shape_edit2"
android:drawableRight="@drawable/item_icon_up"
android:hint="输入停点名/车位号/设备号"
android:inputType="text"
android:textColor="@color/black"
android:textSize="16sp" />
✅步骤三:监听图标点击
//监听图标点击
editText.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
final int DRAWABLE_RIGHT = 2; // 右侧图标的位置
// 检查触摸事件是否为抬起事件
if (event.getAction() == MotionEvent.ACTION_UP) {
// 检查触摸位置是否在右侧图标范围内
if (event.getX() >= (editText.getWidth() - editText.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) {
// 切换图标并处理对应逻辑
if (isIconDown) {
// 当前图标是 item_icon_down,切换为 item_icon_up
editText.setCompoundDrawablesWithIntrinsicBounds(null, null, getResources().getDrawable(R.drawable.item_icon_up), null);
// 处理 item_icon_up 的逻辑
showSuggestions(editText.getText().toString());
if (listPopupWindow != null) listPopupWindow.show();
} else {
// 当前图标是 item_icon_up,切换为 item_icon_down
editText.setCompoundDrawablesWithIntrinsicBounds(null, null, getResources().getDrawable(R.drawable.item_icon_down), null);
// 处理 item_icon_down 的逻辑
showSuggestions(editText.getText().toString());
if (listPopupWindow != null) listPopupWindow.dismiss();
}
// 切换图标状态
isIconDown = !isIconDown;
return true;
}
}
return false;
}
});
setCompoundDrawablesWithIntrinsicBounds
方法的参数分别是设置左、上、右、下位置。
setCompoundDrawablesWithIntrinsicBounds(left, top, right, bottom);
另外定义图标位置的常量如下:
// 定义图标位置的常量,分别为左、上、右、下
final int DRAWABLE_LEFT = 0;
final int DRAWABLE_TOP = 1;
final int DRAWABLE_RIGHT = 2;
final int DRAWABLE_BOTTOM = 3;