在Android里,直接提供的Spinner控件虽然可以实现下拉菜单的效果,但其效果并不理想,很多时候我们需要类似手机QQ那样既可以在文本框中直接输入编辑文字,可以在下拉菜单中选中或者删除菜单选项,并且下拉菜单并不是以遮罩整个手机屏幕方式,而是以浮动在屏幕上的效果出现。下面呢,就来实现一下这些效果。

最后效果为:       

此次主要以EdiText、PopupWindow、ListView及Adapter来实现这种下拉效果。具体实现步骤就不一步步详细介绍了,直接贴完整代码吧,注释比较详细,相信都能看得懂。

//主界面Activity代码:

[html]  view plain copy
  1. public class SelectActivity extends Activity implements Callback {
  2. //PopupWindow对象
  3. private PopupWindow selectPopupWindow= null;
  4. //自定义Adapter
  5. private OptionsAdapter optionsAdapter = null;
  6. //下拉框选项数据源
  7. private ArrayList<String> datas = new ArrayList<String>();;
  8. //下拉框依附组件
  9. private LinearLayout parent;
  10. //下拉框依附组件宽度,也将作为下拉框的宽度
  11. private int pwidth;
  12. //文本框
  13. private EditText et;
  14. //下拉箭头图片组件
  15. private ImageView image;
  16. //恢复数据源按钮
  17. private Button button;
  18. //展示所有下拉选项的ListView
  19. private ListView listView = null;
  20. //用来处理选中或者删除下拉项消息
  21. private Handler handler;
  22. //是否初始化完成标志
  23. private boolean flag = false;
  24. @Override
  25. public void onCreate(Bundle savedInstanceState) {
  26. super.onCreate(savedInstanceState);
  27. setContentView(R.layout.select);
  28. }
  29. /**
  30. * 没有在onCreate方法中调用initWedget(),而是在onWindowFocusChanged方法中调用,
  31. * 是因为initWedget()中需要获取PopupWindow浮动下拉框依附的组件宽度,在onCreate方法中是无法获取到该宽度的
  32. */
  33. @Override
  34. public void onWindowFocusChanged(boolean hasFocus) {
  35. super.onWindowFocusChanged(hasFocus);
  36. while(!flag){
  37. initWedget();
  38. flag = true;
  39. }
  40. }
  41. /**
  42. * 初始化界面控件
  43. */
  44. private void initWedget(){
  45. //初始化Handler,用来处理消息
  46. handler = new Handler(SelectActivity.this);
  47. //初始化界面组件
  48. parent = (LinearLayout)findViewById(R.id.parent);
  49. et = (EditText)findViewById(R.id.edittext);
  50. image = (ImageView)findViewById(R.id.btn_select);
  51. //获取下拉框依附的组件宽度
  52. int width = parent.getWidth();
  53. pwidth = width;
  54. //设置点击下拉箭头图片事件,点击弹出PopupWindow浮动下拉框
  55. image.setOnClickListener(new View.OnClickListener() {
  56. @Override
  57. public void onClick(View v) {
  58. if(flag){
  59. //显示PopupWindow窗口
  60. popupWindwShowing();
  61. }
  62. }
  63. });
  64. //初始化PopupWindow
  65. initPopuWindow();
  66. button = (Button)findViewById(R.id.refresh);
  67. //设置点击事件,恢复下拉框列表数据,没有什么作用,纯粹是为了方便多看几次效果而设置
  68. button.setOnClickListener(new View.OnClickListener() {
  69. @Override
  70. public void onClick(View v) {
  71. initDatas();
  72. optionsAdapter.notifyDataSetChanged();
  73. }
  74. });
  75. }
  76. /**
  77. * 初始化填充Adapter所用List数据
  78. */
  79. private void initDatas(){
  80. datas.clear();
  81. datas.add("北京");
  82. datas.add("上海");
  83. datas.add("广州");
  84. datas.add("深圳");
  85. datas.add("重庆");
  86. datas.add("青岛");
  87. datas.add("石家庄");
  88. }
  89. /**
  90. * 初始化PopupWindow
  91. */
  92. private void initPopuWindow(){
  93. initDatas();
  94. //PopupWindow浮动下拉框布局
  95. View loginwindow = (View)this.getLayoutInflater().inflate(R.layout.options, null);
  96. listView = (ListView) loginwindow.findViewById(R.id.list);
  97. //设置自定义Adapter
  98. optionsAdapter = new OptionsAdapter(this, handler,datas);
  99. listView.setAdapter(optionsAdapter);
  100. selectPopupWindow = new PopupWindow(loginwindow, pwidth,LayoutParams.WRAP_CONTENT, true);
  101. selectPopupWindow.setOutsideTouchable(true);
  102. //这一句是为了实现弹出PopupWindow后,当点击屏幕其他部分及Back键时PopupWindow会消失,
  103. //没有这一句则效果不能出来,但并不会影响背景
  104. //本人能力极其有限,不明白其原因,还望高手、知情者指点一下
  105. selectPopupWindow.setBackgroundDrawable(new BitmapDrawable());
  106. }
  107. /**
  108. * 显示PopupWindow窗口
  109. *
  110. * @param popupwindow
  111. */
  112. public void popupWindwShowing() {
  113. //将selectPopupWindow作为parent的下拉框显示,并指定selectPopupWindow在Y方向上向上偏移3pix,
  114. //这是为了防止下拉框与文本框之间产生缝隙,影响界面美化
  115. //(是否会产生缝隙,及产生缝隙的大小,可能会根据机型、Android系统版本不同而异吧,不太清楚)
  116. selectPopupWindow.showAsDropDown(parent,0,-3);
  117. }
  118. /**
  119. * PopupWindow消失
  120. */
  121. public void dismiss(){
  122. selectPopupWindow.dismiss();
  123. }
  124. /**
  125. * 处理Hander消息
  126. */
  127. @Override
  128. public boolean handleMessage(Message message) {
  129. Bundle data = message.getData();
  130. switch(message.what){
  131. case 1:
  132. //选中下拉项,下拉框消失
  133. int selIndex = data.getInt("selIndex");
  134. et.setText(datas.get(selIndex));
  135. dismiss();
  136. break;
  137. case 2:
  138. //移除下拉项数据
  139. int delIndex = data.getInt("delIndex");
  140. datas.remove(delIndex);
  141. //刷新下拉列表
  142. optionsAdapter.notifyDataSetChanged();
  143. break;
  144. }
  145. return false;
  146. }
  147. }

自定义适配器Adapter代码:

[java]  view plain copy
  1. public class OptionsAdapter extends BaseAdapter {
  2. private ArrayList<String> list = new ArrayList<String>();
  3. private Activity activity = null;
  4. private Handler handler;
  5. /**
  6. * 自定义构造方法
  7. * @param activity
  8. * @param handler
  9. * @param list
  10. */
  11. public OptionsAdapter(Activity activity,Handler handler,ArrayList<String> list){
  12. this.activity = activity;
  13. this.handler = handler;
  14. this.list = list;
  15. }
  16. @Override
  17. public int getCount() {
  18. return list.size();
  19. }
  20. @Override
  21. public Object getItem(int position) {
  22. return list.get(position);
  23. }
  24. @Override
  25. public long getItemId(int position) {
  26. return position;
  27. }
  28. @Override
  29. public View getView(final int position, View convertView, ViewGroup parent) {
  30. ViewHolder holder = null;
  31. if (convertView == null) {
  32. holder = new ViewHolder();
  33. //下拉项布局
  34. convertView = LayoutInflater.from(activity).inflate(R.layout.option_item, null);
  35. holder.textView = (TextView) convertView.findViewById(R.id.item_text);
  36. holder.imageView = (ImageView) convertView.findViewById(R.id.delImage);
  37. convertView.setTag(holder);
  38. } else {
  39. holder = (ViewHolder) convertView.getTag();
  40. }
  41. holder.textView.setText(list.get(position));
  42. //为下拉框选项文字部分设置事件,最终效果是点击将其文字填充到文本框
  43. holder.textView.setOnClickListener(new View.OnClickListener() {
  44. @Override
  45. public void onClick(View v) {
  46. Message msg = new Message();
  47. Bundle data = new Bundle();
  48. //设置选中索引
  49. data.putInt("selIndex", position);
  50. msg.setData(data);
  51. msg.what = 1;
  52. //发出消息
  53. handler.sendMessage(msg);
  54. }
  55. });
  56. //为下拉框选项删除图标部分设置事件,最终效果是点击将该选项删除
  57. holder.imageView.setOnClickListener(new View.OnClickListener() {
  58. @Override
  59. public void onClick(View v) {
  60. Message msg = new Message();
  61. Bundle data = new Bundle();
  62. //设置删除索引
  63. data.putInt("delIndex", position);
  64. msg.setData(data);
  65. msg.what = 2;
  66. //发出消息
  67. handler.sendMessage(msg);
  68. }
  69. });
  70. return convertView;
  71. }
  72. }
  73. class ViewHolder {
  74. TextView textView;
  75. ImageView imageView;
  76. }

主界面布局select.xml文件:

[html]  view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. android:background="#EEEED1"
  7. >
  8. <LinearLayout android:id="@+id/parent" android:layout_width="wrap_content"
[html]  view plain copy
  1. android:layout_height="wrap_content" android:orientation="horizontal"
[html]  view plain copy
  1. android:layout_marginTop="50dp" android:layout_marginLeft="30dp">
  2. <EditText android:id="@+id/edittext" android:layout_width="200dp"  android:singleLine="true"
  3. android:layout_height="40dp" android:background="@drawable/bg1" android:paddingLeft="3dp"/>
  4. <ImageView android:id="@+id/btn_select" android:layout_width="30dp" android:layout_height="40dp"
  5. android:src="@drawable/img1" android:scaleType="fitXY"/>
  6. </LinearLayout>
  7. <Button android:id="@+id/refresh" android:layout_width="wrap_content" android:layout_height="45dp"
  8. android:text="恢复" android:textColor="#000000" android:textSize="20sp"
[html]  view plain copy
  1. android:layout_marginTop="30dp" android:layout_marginLeft="30dp"/>
  2. lt;/LinearLayout>

PopupWindow浮动下拉框布局options.xml文件:

[html]  view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="fill_parent"
  5. android:layout_height="wrap_content"
  6. android:gravity="center_horizontal"
  7. >
  8. <ListView android:id="@+id/list" android:layout_width="fill_parent"
  9. android:layout_height="wrap_content" android:cacheColorHint="#00000000">
  10. </ListView>
  11. </LinearLayout>

下拉选项布局option_item.xml文件:

[html]  view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. android:background="#235654"
  6. >
  7. <RelativeLayout
  8. android:layout_width="wrap_content"
  9. android:layout_height="wrap_content"
  10. android:gravity="center_vertical"
  11. android:minHeight="40dp"
  12. >
  13. <ImageView android:id="@+id/delImage" android:layout_width="20dp"
[html]  view plain copy
  1. android:layout_height="wrap_content" android:src="@drawable/del" android:textSize="18sp"
  2. android:layout_alignParentRight="true" android:layout_marginRight="10dp"/>
  3. <TextView android:id="@+id/item_text"  android:layout_height="wrap_content"
  4. android:layout_width="fill_parent" android:layout_toLeftOf="@id/delImage"
  5. android:paddingLeft="5dp" android:layout_alignParentLeft="true"></TextView>
  6. </RelativeLayout>
  7. </LinearLayout>

Android实现仿QQ登录可编辑下拉菜单相关推荐

  1. android 实现仿QQ登录可编辑下拉菜单

    今天,简单讲讲android里如何实现向QQ一样的登录后记住用户名的下拉框. 这个其实也很简单,网上搜索了一下,很多相关的资料,基本都是PopupWindow+ListView的方式,实现起来比较灵活 ...

  2. ​Android实现仿QQ登录可编辑下拉菜单

    Android实现仿QQ登录可编辑下拉菜单 在Android里,直接提供的Spinner控件虽然可以实现下拉菜单的效果,但其效果并不理想,很多时候我们需要类似手机QQ那样既可以在文本框中直接输入编辑文 ...

  3. Android实现可编辑下拉菜单

    Android实现仿QQ登录可编辑下拉菜单 在Android里,直接提供的Spinner控件虽然可以实现下拉菜单的效果,但其效果并不理想,很多时候我们需要类似手机QQ那样既可以在文本框中直接输入编辑文 ...

  4. android studio 下拉菜单,怎么在android studio中使用Spinner实现一个下拉菜单

    怎么在android studio中使用Spinner实现一个下拉菜单 发布时间:2021-03-23 14:56:15 来源:亿速云 阅读:92 作者:Leah 这期内容当中小编将会给大家带来有关怎 ...

  5. Android实现仿QQ登录界面背景动画效果

    登录QQ的时候,我们会看到在登录界面的背景不是静态的,而是一段动画效果,刚开始觉得蛮好奇的,现在我们也来实现一下这种效果,实现起来还是挺简单的. 实现步骤: 1.自定义CustomVideoView类 ...

  6. Android仿手机淘宝多级下拉菜单

    我们在常用的电商或者旅游APP中,例如美团,手机淘宝等等,都能够看的到有那种下拉式的二级列表菜单.具体如图所示: 上面两张图就是美团的一个二级列表菜单的一个展示.我相信很多人都想开发一个跟它一样的功能 ...

  7. web前端页面——移动端简单登录页面、下拉菜单(代码详细注释)

      今天跟着专业老师复习了一下前端,感觉好多都已经忘记了,我将今天复习的一些重点整理出来. https://blog.csdn.net/hanhanwanghaha宝藏女孩 欢迎您的关注! 欢迎关注微 ...

  8. Android高仿QQ消息列表、侧拉删除菜单按钮效果

    目    录(本篇字数:3000) 介绍 Item布局 自定义存放Item父容器 Bug分析 ·一.解决滑动冲突 二.解决Item点击事件的冲突 三.限制只能有一个menu被打开 博文续篇 ListV ...

  9. 仿QQ空间,百思不得姐下拉刷新图片放大

    1.概述 实习生进阶到项目部分会带他们做一个百思不得姐项目,那么个人主页就有类似于QQ空间下拉图片放大的效果,趁着现在还闲就实现一下效果: 2.实现 1. 效果分析 ScrollView和ListVi ...

最新文章

  1. 在Java SE中使用Hibernate处理数据
  2. android ios 上传图片到服务器,.net 接收ios, android的上传图片
  3. Replicate(网络复制),ActorRole(角色),Ownership(所有权)以及RPC(远程调用)等等...
  4. spring boot 微服务集群 + 注册中心
  5. apache wicket_Apache Wicket:记住我的功能
  6. ElasticSearch的Object数据类型
  7. fabric node enrollAdmin.js 报错SyntaxError: Unexpected token function at createScript (vm.js:56:10)
  8. 学习笔记之rpm程序包管理功能解析
  9. socket.io实现客户端和服务端的双向通信
  10. js手机号批量滚动抽奖代码实现
  11. 计算两向量的旋转角(转)
  12. 数据类型不一致: 应为 NUMBER, 但却获得 BINARY
  13. Pegasus Serial Port Tool @ Simplicity Version 串口测试工具简化版发布
  14. swal如何加入html语言,前端基础(九):SweetAlert(弹出框)
  15. 音乐、音效素材库,好听的BGM都在这~
  16. 第一章 初探Swing
  17. 招商银行信用卡中心18秋招题解
  18. gym100676 [小熊骑士限定]2015 ACM Arabella Collegiate Programming Contest
  19. 图像配准(匹配)与变化检测
  20. IT服务管理指标体系与报表体系

热门文章

  1. UVM基础-Sequence、Sequencer(二)
  2. ce查找人物基址_关于CE找基址的一些基础概念
  3. android Q HIDL(小屏显示)
  4. 爱奇艺内容中台数据中心的设计与实现
  5. 扣血抖动和FPS显示
  6. 全球开发者各出奇招:我们想这样适配iPhone X
  7. C_sharp-gives-OJ-background-test-data
  8. vue判断有没有滚动条
  9. Python骚操作 | 还原已撤回的微信消息
  10. 使用Excel中PPMT函数和IPMT函数进行等额本息还款的计算方法