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;
相关推荐
JJay.3 分钟前
Kotlin 高阶函数学习指南
android·开发语言·kotlin
jinanwuhuaguo7 分钟前
截止到4月8日,OpenClaw 2026年4月更新深度解读剖析:从“能力回归”到“信任内建”的范式跃迁
android·开发语言·人工智能·深度学习·kotlin
JJay.1 小时前
Android Kotlin 协程使用指南
android·开发语言·kotlin
BLUcoding1 小时前
Android 布局介绍
android
summerkissyou19872 小时前
android-蓝牙-状态和协议值总结及监听例子
android·蓝牙
徒 花2 小时前
数据库知识复习05
android·数据库
提子拌饭1334 小时前
番茄时间管理:鸿蒙Flutter 实现的高效时间管理工具
android·flutter·华为·架构·开源·harmonyos·鸿蒙
4311媒体网4 小时前
帝国CMS二次开发实战:精准实现“最新资讯”标识与高亮判断
android
BLUcoding4 小时前
Android 轻量级本地存储 SharedPreferences
android
冬奇Lab4 小时前
Camera HAL3 接口:Android 相机的真正底牌
android·音视频开发·源码阅读