转载请注明出处:http://blog.csdn.net/l1028386804/article/details/48101651

做过Android开发的童鞋,一般都会遇到这样一种情况,就是Android中原有的下拉控件Spinner过于单调和简单,不能够满足我们实际开发的需求了,这时候就需要我们自己自定义下拉菜单来实现相应的功能,那么,如何实现自定义下拉菜单呢?下面我就来和大家一起实现这个功能。

一、原理

我们这个下拉菜单展示的内容主要以ListView实现,在界面上放置一个文本框,文本框右侧放置一个向下的箭头图标,表示可以点击下拉。然后创建一个item.xml布局文件,这个布局文件展示的就是ListView的条目信息,条目中有一个图片,表示头像,一串数字表示qq号(暂时以显示qq号为例),后面一个删除按钮。所有的数据封装在ListView中。然后我们将这个ListView以PopupWindow的形式显示在文本框的下面。

当ListView不显示的时候,点击文本框右侧的下拉图标,则弹出PopupWindow显示ListView

当ListView显示的时候,点击文本框右侧的下拉图标,则隐藏PopupWindow从而隐藏ListView

点击ListView中每一个条目后删除图标的时候,相应的条目就会从listView中消失。

二、实现

1、MainActivity

程序很简单,我将所有的java代码都写在了MainActivity中,我们还是分解来看这个类。

1)属性字段

每个字段代表的含义见代码注释

具体代码实现如下:

//界面控件private ImageButton spinner;private EditText et_name;//构造qq号用到的集合private List<String> names = new ArrayList<String>();//布局加载器private LayoutInflater mInflater;//自定义适配器private MyAdapter mAdapter;//PopupWindowprivate PopupWindow pop;//是否显示PopupWindow,默认不显示private boolean isPopShow = false;

2)自定义Adapter

同样,为了在ListView中更好的显示数据,我们还是用到了自定义Adapter

具体代码实现如下:

/** * 自定义Adapter * @author liuyazhuang * */private class MyAdapter extends BaseAdapter{@Overridepublic int getCount() {// TODO Auto-generated method stubreturn names.size();}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn names.get(position);}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position;}@Overridepublic View getView(final int position, View convertView, ViewGroup parent) {View view = mInflater.inflate(R.layout.item, null);final TextView tv_name = (TextView) view.findViewById(R.id.tv_name);tv_name.setText(names.get(position));ImageButton delete = (ImageButton) view.findViewById(R.id.delete);//设置按钮的监听事件delete.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubnames.remove(position);isPopShow = true;mAdapter.notifyDataSetChanged();}});//设置按钮的监听事件tv_name.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubet_name.setText(names.get(position));pop.dismiss();}});return view;}} 

3)onCreate方法

这个方法中主要实现的功能就是,初始化界面布局,为属性字段赋值,构造要在ListView中显示的数据,同时为相应的按钮设置点击事件,控制PopupWindow的显示和隐藏。

具体实现代码如下:

@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//构造qq账号for(int i = 10000; i < 10030; i++){names.add(String.valueOf(i));}spinner = (ImageButton) findViewById(R.id.spinner);et_name = (EditText) findViewById(R.id.et_name);mInflater = LayoutInflater.from(MainActivity.this);mAdapter = new MyAdapter();spinner.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubif(pop == null){ListView listView = new ListView(MainActivity.this);listView.setCacheColorHint(0x00000000);listView.setAdapter(mAdapter);pop = new PopupWindow(listView, et_name.getWidth(), LayoutParams.WRAP_CONTENT, true);pop.setBackgroundDrawable(new ColorDrawable(0x00000000));isPopShow = true;}if(isPopShow){pop.showAsDropDown(et_name, 0, 0);isPopShow = false;}else{pop.dismiss();isPopShow = true;}}});}

4)完整代码如下:

package com.lyz.spiner.activity;import java.util.ArrayList;import java.util.List;import android.os.Bundle;import android.app.Activity;import android.graphics.drawable.ColorDrawable;import android.view.LayoutInflater;import android.view.Menu;import android.view.View;import android.view.ViewGroup;import android.view.ViewGroup.LayoutParams;import android.widget.BaseAdapter;import android.widget.EditText;import android.widget.ImageButton;import android.widget.ListView;import android.widget.PopupWindow;import android.widget.TextView;/** * 程序主入口 * @author liuyazhuang * */public class MainActivity extends Activity {//界面控件private ImageButton spinner;private EditText et_name;//构造qq号用到的集合private List<String> names = new ArrayList<String>();//布局加载器private LayoutInflater mInflater;//自定义适配器private MyAdapter mAdapter;//PopupWindowprivate PopupWindow pop;//是否显示PopupWindow,默认不显示private boolean isPopShow = false;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//构造qq账号for(int i = 10000; i < 10030; i++){names.add(String.valueOf(i));}spinner = (ImageButton) findViewById(R.id.spinner);et_name = (EditText) findViewById(R.id.et_name);mInflater = LayoutInflater.from(MainActivity.this);mAdapter = new MyAdapter();spinner.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubif(pop == null){ListView listView = new ListView(MainActivity.this);listView.setCacheColorHint(0x00000000);listView.setAdapter(mAdapter);pop = new PopupWindow(listView, et_name.getWidth(), LayoutParams.WRAP_CONTENT, true);pop.setBackgroundDrawable(new ColorDrawable(0x00000000));isPopShow = true;}if(isPopShow){pop.showAsDropDown(et_name, 0, 0);isPopShow = false;}else{pop.dismiss();isPopShow = true;}}});}/** * 自定义Adapter * @author liuyazhuang * */private class MyAdapter extends BaseAdapter{@Overridepublic int getCount() {// TODO Auto-generated method stubreturn names.size();}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn names.get(position);}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position;}@Overridepublic View getView(final int position, View convertView, ViewGroup parent) {View view = mInflater.inflate(R.layout.item, null);final TextView tv_name = (TextView) view.findViewById(R.id.tv_name);tv_name.setText(names.get(position));ImageButton delete = (ImageButton) view.findViewById(R.id.delete);//设置按钮的监听事件delete.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubnames.remove(position);isPopShow = true;mAdapter.notifyDataSetChanged();}});//设置按钮的监听事件tv_name.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubet_name.setText(names.get(position));pop.dismiss();}});return view;}} @Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}}

2、主布局文件activity_main.xml

具体实现代码如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"     android:background="@android:color/black">    <EditText        android:id="@+id/et_name"        android:layout_width="200dip"        android:layout_height="wrap_content"android:layout_centerHorizontal="true"android:hint="请输入账号" />    <ImageButton     android:id="@+id/spinner"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:background="@drawable/button"    android:layout_alignTop="@id/et_name"    android:layout_alignRight="@id/et_name"    android:layout_alignBottom="@id/et_name"/></RelativeLayout>

3、条目布局文件item.xml

具体实现代码如下:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="horizontal"     android:gravity="center_vertical">    <ImageView         android:id="@+id/header"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/user"/>        <TextView         android:id="@+id/tv_name"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_weight="1"/>        <ImageButton         android:id="@+id/delete"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="@drawable/delete"/></LinearLayout>

4、AndroidManifest.xml

最后贴出AndroidManifest.xml的代码

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.lyz.spiner.activity"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="18" />    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name="com.lyz.spiner.activity.MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>

三、运行效果


四、温馨提示

大家可以到链接http://download.csdn.net/detail/l1028386804/9062795下载Android自定义下拉菜单示例完整源代码

本实例中,为了方面,我把一些文字直接写在了布局文件中和相关的类中,大家在真实的项目中要把这些文字写在string.xml文件中,在外部引用这些资源,切记,这是作为一个Android程序员最基本的开发常识和规范,我在这里只是为了方便直接写在了类和布局文件中。

更多相关文章

  1. Android(安卓)Drawable 系列——ClipDrawable
  2. android开机自动启动指定app
  3. 关于Edittext点击弹出软键盘,布局上移标题消失问题,微信聊天界面
  4. 鸿洋大神2016年所有文章链接
  5. Android(安卓)Studio 生成含第三方jar包 以及引入指定的jar
  6. Android(安卓)程序员学习 iOS ——UIViewController 和 Layout S
  7. android之Activity基本跳转
  8. 还在用枚举?我早就抛弃了!(Android(安卓)注解详解)
  9. android中的5个布局方式

随机推荐

  1. android 横竖屏
  2. Android中获取应用程序(包)的信息-----Pa
  3. Android第九讲——网络(六)xUtils
  4. 解决Cocos2d-x3.1编译生成Android程序出
  5. Android(安卓)Dialog 去除背景内容模糊
  6. AndFire防火墙1.2版本发布
  7. android之TextVIew与Button交互
  8. 3.Retrofit上传头像给后端
  9. 实现类似Android联系人搜索功能
  10. android App Widgets