转载请注明出处: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; //PopupWindow private PopupWindow pop; //是否显示PopupWindow,默认不显示 private boolean isPopShow = false;
2)自定义Adapter
同样,为了在ListView中更好的显示数据,我们还是用到了自定义Adapter
具体代码实现如下:
/** * 自定义Adapter * @author liuyazhuang * */ private class MyAdapter extends BaseAdapter{ @Override public int getCount() { // TODO Auto-generated method stub return names.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return names.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public 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() { @Override public void onClick(View v) { // TODO Auto-generated method stub names.remove(position); isPopShow = true; mAdapter.notifyDataSetChanged(); } }); //设置按钮的监听事件 tv_name.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub et_name.setText(names.get(position)); pop.dismiss(); } }); return view; } }
3)onCreate方法
这个方法中主要实现的功能就是,初始化界面布局,为属性字段赋值,构造要在ListView中显示的数据,同时为相应的按钮设置点击事件,控制PopupWindow的显示和隐藏。
具体实现代码如下:
@Override protected 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() { @Override public void onClick(View v) { // TODO Auto-generated method stub if(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; //PopupWindow private PopupWindow pop; //是否显示PopupWindow,默认不显示 private boolean isPopShow = false; @Override protected 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() { @Override public void onClick(View v) { // TODO Auto-generated method stub if(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{ @Override public int getCount() { // TODO Auto-generated method stub return names.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return names.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public 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() { @Override public void onClick(View v) { // TODO Auto-generated method stub names.remove(position); isPopShow = true; mAdapter.notifyDataSetChanged(); } }); //设置按钮的监听事件 tv_name.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub et_name.setText(names.get(position)); pop.dismiss(); } }); return view; } } @Override public 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程序员最基本的开发常识和规范,我在这里只是为了方便直接写在了类和布局文件中。
版权声明:本文为博主原创文章,未经博主允许不得转载。