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

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


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

最后效果为:       

 

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

 

 

//主界面Activity代码:



  1. public class SelectActivity extends Activity implements Callback {  

  2.     //PopupWindow对象  

  3.     private PopupWindow selectPopupWindownull;  

  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.       

  25.     @Override  

  26.     public void onCreate(Bundle savedInstanceState) {  

  27.         super.onCreate(savedInstanceState);  

  28.         setContentView(R.layout.select);  

  29.     }  

  30.   

  31.     /**  

  32.      * 没有在onCreate方法中调用initWedget(),而是在onWindowFocusChanged方法中调用,  

  33.      * 是因为initWedget()中需要获取PopupWindow浮动下拉框依附的组件宽度,在onCreate方法中是无法获取到该宽度的  

  34.      */  

  35.     @Override  

  36.     public void onWindowFocusChanged(boolean hasFocus) {  

  37.         super.onWindowFocusChanged(hasFocus);  

  38.         while(!flag){  

  39.             initWedget();  

  40.             flag = true;  

  41.         }  

  42.           

  43.     }  

  44.       

  45.     /**  

  46.      * 初始化界面控件  

  47.      */  

  48.     private void initWedget(){  

  49.         //初始化Handler,用来处理消息  

  50.         handler = new Handler(SelectActivity.this);  

  51.           

  52.         //初始化界面组件  

  53.         parent = (LinearLayout)findViewById(R.id.parent);  

  54.         et = (EditText)findViewById(R.id.edittext);  

  55.         image = (ImageView)findViewById(R.id.btn_select);  

  56.           

  57.           

  58.         //获取下拉框依附的组件宽度  

  59.         int width = parent.getWidth();  

  60.         pwidth = width;  

  61.           

  62.         //设置点击下拉箭头图片事件,点击弹出PopupWindow浮动下拉框  

  63.         image.setOnClickListener(new View.OnClickListener() {  

  64.             @Override  

  65.             public void onClick(View v) {  

  66.                 if(flag){  

  67.                     //显示PopupWindow窗口  

  68.                     popupWindwShowing();  

  69.                 }  

  70.             }  

  71.         });  

  72.           

  73.         //初始化PopupWindow  

  74.         initPopuWindow();  

  75.           

  76.         button = (Button)findViewById(R.id.refresh);  

  77.         //设置点击事件,恢复下拉框列表数据,没有什么作用,纯粹是为了方便多看几次效果而设置  

  78.         button.setOnClickListener(new View.OnClickListener() {  

  79.             @Override  

  80.             public void onClick(View v) {  

  81.                 initDatas();  

  82.                 optionsAdapter.notifyDataSetChanged();  

  83.             }  

  84.         });  

  85.     }  

  86.   

  87.     /**  

  88.      * 初始化填充Adapter所用List数据  

  89.      */  

  90.     private void initDatas(){  

  91.           

  92.          datas.clear();  

  93.            

  94.          datas.add("北京");  

  95.          datas.add("上海");  

  96.          datas.add("广州");  

  97.          datas.add("深圳");  

  98.          datas.add("重庆");  

  99.          datas.add("青岛");  

  100.          datas.add("石家庄");  

  101.     }  

  102.       

  103.      /**  

  104.      * 初始化PopupWindow  

  105.      */   

  106.     private void initPopuWindow(){   

  107.           

  108.         initDatas();  

  109.           

  110.         //PopupWindow浮动下拉框布局  

  111.         View loginwindow = (View)this.getLayoutInflater().inflate(R.layout.options, null);   

  112.         listView = (ListView) loginwindow.findViewById(R.id.list);   

  113.           

  114.         //设置自定义Adapter  

  115.         optionsAdapter = new OptionsAdapter(this, handler,datas);   

  116.         listView.setAdapter(optionsAdapter);   

  117.           

  118.         selectPopupWindow = new PopupWindow(loginwindow, pwidth,LayoutParams.WRAP_CONTENT, true);   

  119.           

  120.         selectPopupWindow.setOutsideTouchable(true);   

  121.           

  122.         //这一句是为了实现弹出PopupWindow后,当点击屏幕其他部分及Back键时PopupWindow会消失,  

  123.         //没有这一句则效果不能出来,但并不会影响背景  

  124.         //本人能力极其有限,不明白其原因,还望高手、知情者指点一下  

  125.         selectPopupWindow.setBackgroundDrawable(new BitmapDrawable());    

  126.     }   

  127.   

  128.       

  129.       

  130.     /**  

  131.      * 显示PopupWindow窗口  

  132.      *   

  133.      * @param popupwindow  

  134.      */   

  135.     public void popupWindwShowing() {   

  136.        //将selectPopupWindow作为parent的下拉框显示,并指定selectPopupWindow在Y方向上向上偏移3pix,  

  137.        //这是为了防止下拉框与文本框之间产生缝隙,影响界面美化  

  138.        //(是否会产生缝隙,及产生缝隙的大小,可能会根据机型、Android系统版本不同而异吧,不太清楚)  

  139.        selectPopupWindow.showAsDropDown(parent,0,-3);   

  140.     }   

  141.        

  142.     /**  

  143.      * PopupWindow消失  

  144.      */   

  145.     public void dismiss(){   

  146.         selectPopupWindow.dismiss();   

  147.     }  

  148.   

  149.     /**  

  150.      * 处理Hander消息  

  151.      */  

  152.     @Override  

  153.     public boolean handleMessage(Message message) {  

  154.         Bundle data = message.getData();  

  155.         switch(message.what){  

  156.             case 1:  

  157.                 //选中下拉项,下拉框消失  

  158.                 int selIndex = data.getInt("selIndex");  

  159.                 et.setText(datas.get(selIndex));  

  160.                 dismiss();  

  161.                 break;  

  162.             case 2:  

  163.                 //移除下拉项数据  

  164.                 int delIndex = data.getInt("delIndex");  

  165.                 datas.remove(delIndex);  

  166.                 //刷新下拉列表  

  167.                 optionsAdapter.notifyDataSetChanged();  

  168.                 break;  

  169.         }  

  170.         return false;  

  171.     }   

  172. }  


自定义适配器Adapter代码:


  1. public class OptionsAdapter extends BaseAdapter {  

  2.   

  3.     private ArrayList<String> list = new ArrayList<String>();   

  4.     private Activity activity = null;   

  5.     private Handler handler;  

  6.       

  7.     /** 

  8.      * 自定义构造方法 

  9.      * @param activity 

  10.      * @param handler 

  11.      * @param list 

  12.      */  

  13.     public OptionsAdapter(Activity activity,Handler handler,ArrayList<String> list){  

  14.         this.activity = activity;  

  15.         this.handler = handler;  

  16.         this.list = list;  

  17.     }  

  18.       

  19.     @Override  

  20.     public int getCount() {  

  21.         return list.size();  

  22.     }  

  23.   

  24.     @Override  

  25.     public Object getItem(int position) {  

  26.         return list.get(position);  

  27.     }  

  28.   

  29.     @Override  

  30.     public long getItemId(int position) {  

  31.         return position;  

  32.     }  

  33.   

  34.     @Override  

  35.     public View getView(final int position, View convertView, ViewGroup parent) {  

  36.         ViewHolder holder = null;   

  37.         if (convertView == null) {   

  38.             holder = new ViewHolder();   

  39.             //下拉项布局  

  40.             convertView = LayoutInflater.from(activity).inflate(R.layout.option_item, null);   

  41.             holder.textView = (TextView) convertView.findViewById(R.id.item_text);   

  42.             holder.imageView = (ImageView) convertView.findViewById(R.id.delImage);   

  43.               

  44.             convertView.setTag(holder);   

  45.         } else {   

  46.             holder = (ViewHolder) convertView.getTag();   

  47.         }   

  48.           

  49.         holder.textView.setText(list.get(position));  

  50.           

  51.         //为下拉框选项文字部分设置事件,最终效果是点击将其文字填充到文本框  

  52.         holder.textView.setOnClickListener(new View.OnClickListener() {  

  53.             @Override  

  54.             public void onClick(View v) {  

  55.                 Message msg = new Message();  

  56.                 Bundle data = new Bundle();  

  57.                 //设置选中索引  

  58.                 data.putInt("selIndex", position);  

  59.                 msg.setData(data);  

  60.                 msg.what = 1;  

  61.                 //发出消息  

  62.                 handler.sendMessage(msg);  

  63.             }  

  64.         });  

  65.           

  66.         //为下拉框选项删除图标部分设置事件,最终效果是点击将该选项删除  

  67.         holder.imageView.setOnClickListener(new View.OnClickListener() {  

  68.             @Override  

  69.             public void onClick(View v) {  

  70.                 Message msg = new Message();  

  71.                 Bundle data = new Bundle();  

  72.                 //设置删除索引  

  73.                 data.putInt("delIndex", position);  

  74.                 msg.setData(data);  

  75.                 msg.what = 2;  

  76.                 //发出消息  

  77.                 handler.sendMessage(msg);  

  78.             }  

  79.         });  

  80.           

  81.         return convertView;   

  82.     }  

  83.   

  84. }  

  85.   

  86.   

  87. class ViewHolder {   

  88.     TextView textView;   

  89.     ImageView imageView;   

  90. }   


 


 

主界面布局select.xml文件:


  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"   


  1. android:layout_height="wrap_content" android:orientation="horizontal"   


  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"   


  1. android:layout_marginTop="30dp" android:layout_marginLeft="30dp"/>  

  2. lt;/LinearLayout>  

 

 

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


  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文件:


  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"  


  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> 


你可能感兴趣的:(ListView,Adapter,PopupWindow,EdiText)