Android EditText+ListPopupWindow实现可编辑的下拉列表

Android EditText+ListPopupWindow实现可编辑的下拉列表

📖1. 可编辑的下拉列表

效果图:

✅步骤一:准备视图

EditText视图:

xml 复制代码
 <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 复制代码
<?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>

✅步骤二:封装显示方法

java 复制代码
    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.获取输入框

java 复制代码
EditText edit_text = findViewById(R.id.edit_text);//输入框

2.生成下拉数据(这里的数据可换成真实的数据库数据),监听文本变化

java 复制代码
 		//生成数据
		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 复制代码
<?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 复制代码
<?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>

里面的图片可直接再阿里巴巴图标库搜索"上拉"、"下拉"即可

地址:https://www.iconfont.cn/

✅步骤二:drawableRight属性

编辑框添加drawableRight属性,EditText可以添加上下左右图片资源,我们添加右边即可。

xml 复制代码
<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" />

✅步骤三:监听图标点击

java 复制代码
       //监听图标点击
        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方法的参数分别是设置左、上、右、下位置。

java 复制代码
setCompoundDrawablesWithIntrinsicBounds(left, top, right, bottom);

另外定义图标位置的常量如下:

java 复制代码
      // 定义图标位置的常量,分别为左、上、右、下
        final int DRAWABLE_LEFT = 0;
        final int DRAWABLE_TOP = 1;
        final int DRAWABLE_RIGHT = 2;
        final int DRAWABLE_BOTTOM = 3;
相关推荐
_李小白7 小时前
【android opencv学习笔记】Day 28: 滤波算法之中值滤波器
android·opencv·学习
代龙涛10 小时前
WordPress page.php 页面模板与自定义模板使用方法
android·开发语言·php
爱莉希雅&&&11 小时前
zabbix快速搭建和使用
android·linux·数据库·zabbix·监控
zfoo-framework12 小时前
理解kotlin limitedParallelism(1)与Actor模型
android·开发语言·kotlin
2401_8657213314 小时前
御网杯初赛2026
android
葱段15 小时前
【Compose】输入框(TextField)点击空白处失焦并关闭软键盘
android
刮风那天17 小时前
Android Framework 核心架构图
android
__Witheart__17 小时前
3588 安卓编译空间不足报错
android
aaajj17 小时前
【Android】手机屏幕劫持防护
android·智能手机
写做四月一日的四月一日17 小时前
在安卓手机上安装小龙虾openclaw并配置QQ机器人接入
android·人工智能