Android 简单的下拉选择框实现

要实现这种效果,目前知道的方法有以下两种,Spinner 和 ListPopupWindow,当然肯定还有很多别的方法,这里我们先尝试使用ListPopupWindow来实现这个效果;

以下是一个简单的demo:

java 复制代码
public class MainActivity extends AppCompatActivity {

    private List<String> dataList;
    private ListPopupWindow listPopupWindow;
    private Button showPopupButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 初始化数据
        initData();

        // 初始化 ListPopupWindow
        listPopupWindow = new ListPopupWindow(this);
        ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, dataList);
        listPopupWindow.setAdapter(adapter);
        listPopupWindow.setAnchorView(showPopupButton); // 设置锚点

        // 设置列表项点击监听器
        listPopupWindow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String selectedItem = dataList.get(position);
                Toast.makeText(MainActivity.this, "Selected: " + selectedItem, Toast.LENGTH_SHORT).show();
                listPopupWindow.dismiss(); // 点击后隐藏 ListPopupWindow
            }
        });

        // 初始化显示下拉选择框的按钮
        showPopupButton = findViewById(R.id.show_popup_button);
        showPopupButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                listPopupWindow.show(); // 点击按钮显示 ListPopupWindow
            }
        });
    }

    private void initData() {
        // 模拟数据
        dataList = new ArrayList<>();
        dataList.add("Option 1");
        dataList.add("Option 2");
        dataList.add("Option 3");
        // 添加更多选项...
    }
}

在这个示例中,我们创建了一个包含几个选项的数据列表 dataList,然后使用 ArrayAdapter 将它们设置到 ListPopupWindow 中。接着,我们为 ListPopupWindow 设置了一个按钮作为锚点,并设置了按钮的点击监听器,在点击按钮时显示 ListPopupWindow。最后,我们为 ListPopupWindow 设置了一个列表项点击监听器,在用户点击列表项时处理相应的逻辑,并隐藏 ListPopupWindow

确保您的布局文件中包含一个按钮控件(Button),用于触发显示 ListPopupWindow 的操作。

以上只是一个简单的demo,我们可能会遇到一些新的需求,如下

如果已经选中了某个选项,并且更新了按钮的文本为选中的选项内容,当再次点击按钮显示下拉选择框时,您可以让下拉框中的列表项与按钮内容匹配,并将匹配项显示为选中状态。

下面是一种实现方式:

java 复制代码
public class MainActivity extends AppCompatActivity {

    private List<String> dataList;
    private ListPopupWindow listPopupWindow;
    private Button showPopupButton;
    private String selectedItem;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 初始化数据
        initData();

        // 初始化 ListPopupWindow
        listPopupWindow = new ListPopupWindow(this);
        ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, dataList);
        listPopupWindow.setAdapter(adapter);
        listPopupWindow.setAnchorView(showPopupButton); // 设置锚点

        // 设置列表项点击监听器
        listPopupWindow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                selectedItem = dataList.get(position);
                showPopupButton.setText(selectedItem); // 更新按钮文本为选中的选项内容
                Toast.makeText(MainActivity.this, "Selected: " + selectedItem, Toast.LENGTH_SHORT).show();
                adapter.notifyDataSetChanged(); // 刷新适配器以更新选中状态
                listPopupWindow.dismiss(); // 点击后隐藏 ListPopupWindow
            }
        });

        // 初始化显示下拉选择框的按钮
        showPopupButton = findViewById(R.id.show_popup_button);
        showPopupButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                listPopupWindow.show(); // 点击按钮显示 ListPopupWindow
                // 选中当前按钮文本所对应的选项
                int index = dataList.indexOf(showPopupButton.getText().toString());
                listPopupWindow.setSelection(index);
            }
        });
    }

    private void initData() {
        // 模拟数据
        dataList = new ArrayList<>();
        dataList.add("Option 1");
        dataList.add("Option 2");
        dataList.add("Option 3");
        // 添加更多选项...
    }
}

在这个示例中,我们在点击按钮时设置了下拉框中的选项为当前按钮的文本对应的选项,并通过 listPopupWindow.setSelection(index) 方法来实现。这样,下拉框中的选项就会显示为选中状态。

我们继续:listPopupWindow.setSelection(index) 的话,如果每个index 的选中效果不一样应该怎么处理呢?

如果每个选项的选中状态效果不一样,可以在适配器中根据选中状态来设置不同的样式。在 getView() 方法中,可以根据每个选项的选中状态来设置其样式,以反映其选中状态。

下面是一个修改后的示例代码,演示如何根据每个选项的选中状态来设置不同的样式:

java 复制代码
public class MainActivity extends AppCompatActivity {

    private List<String> dataList;
    private List<Boolean> itemSelectedStates;
    private ListPopupWindow listPopupWindow;
    private Button showPopupButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 初始化数据
        initData();

        // 初始化 ListPopupWindow
        listPopupWindow = new ListPopupWindow(this);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 0, dataList) {
            @Override
            public View getView(int position, View convertView, android.view.ViewGroup parent) {
                // 获取当前选项的视图
                View view = super.getView(position, convertView, parent);
                TextView textView = (TextView) view;
                // 设置选项的样式
                if (itemSelectedStates.get(position)) {
                    // 如果选项被选中,设置为粗体字体,背景色为灰色
                    textView.setAllCaps(true);
                    textView.setBackgroundColor(getResources().getColor(android.R.color.darker_gray));
                } else {
                    // 如果选项未选中,恢复普通字体样式,背景色为白色
                    textView.setAllCaps(false);
                    textView.setBackgroundColor(getResources().getColor(android.R.color.white));
                }
                return view;
            }
        };
        listPopupWindow.setAdapter(adapter);
        listPopupWindow.setAnchorView(showPopupButton); // 设置锚点

        // 设置列表项点击监听器
        listPopupWindow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String selectedItem = dataList.get(position);
                Toast.makeText(MainActivity.this, "Selected: " + selectedItem, Toast.LENGTH_SHORT).show();
                // 更新选中状态数组
                for (int i = 0; i < itemSelectedStates.size(); i++) {
                    itemSelectedStates.set(i, (i == position));
                }
                adapter.notifyDataSetChanged(); // 刷新适配器以更新选中状态
                listPopupWindow.dismiss(); // 点击后隐藏 ListPopupWindow
            }
        });

        // 初始化显示下拉选择框的按钮
        showPopupButton = findViewById(R.id.show_popup_button);
        showPopupButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                listPopupWindow.show(); // 点击按钮显示 ListPopupWindow
            }
        });
    }

    private void initData() {
        // 模拟数据
        dataList = new ArrayList<>();
        dataList.add("Option 1");
        dataList.add("Option 2");
        dataList.add("Option 3");
        // 添加更多选项...

        // 初始化选中状态数组,默认第一个选项为选中状态
        itemSelectedStates = new ArrayList<>();
        for (int i = 0; i < dataList.size(); i++) {
            itemSelectedStates.add(false);
        }
    }
}

在这个示例中,我们重写了 ArrayAdaptergetView() 方法,在其中根据每个选项的选中状态来设置不同的样式。当选项被选中时,我们将其字体设置为粗体并将背景色设为灰色,未选中时恢复普通字体样式并将背景色设为白色。这样可以让每个选项的选中状态效果不一样。

相关推荐
执明wa15 小时前
LayoutInflater详解: XML是如何变成View的?
android·xml·开发语言·android studio
404_coder15 小时前
源码视角下的 Android 开机流程:从 Zygote、SystemServer 到 Launcher
android
二流小码农15 小时前
鸿蒙开发:以登录案例了解代码架构MVVM
android·ios·harmonyos
用户693717500138416 小时前
从代码生产者到 AI 协作者:软件工程师的角色重构
android·前端·后端
GitLqr16 小时前
别在 Flutter 的 main() 里乱锁屏幕方向,小心 iPad 分屏功能被你搞没了
android·flutter·ios
sg_knight16 小时前
MySQL 存储过程详解:从入门到实战
android·数据库·mysql·database·dba·关系型数据库·db
爱笑鱼16 小时前
Binder(四):ioctl(BINDER_WRITE_READ) 之后,事务怎样到达目标进程?
android
AFinalStone17 小时前
Android 7系统休眠唤醒(二)开机全链路—BootROM到Launcher
android·电源管理·休眠唤醒
Mr YiRan17 小时前
Android NDK开发之统计到未被回收的图片
android