您的位置:首页 > 移动开发 > Android开发

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

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

最后效果为:






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





//主界面Activity代码:

[html] view
plaincopy

public class SelectActivity extends Activity implements Callback {

//PopupWindow对象

private PopupWindow selectPopupWindow= null;

//自定义Adapter

private OptionsAdapter optionsAdapter = null;

//下拉框选项数据源

private ArrayList<String> datas = new ArrayList<String>();;

//下拉框依附组件

private LinearLayout parent;

//下拉框依附组件宽度,也将作为下拉框的宽度

private int pwidth;

//文本框

private EditText et;

//下拉箭头图片组件

private ImageView image;

//恢复数据源按钮

private Button button;

//展示所有下拉选项的ListView

private ListView listView = null;

//用来处理选中或者删除下拉项消息

private Handler handler;

//是否初始化完成标志

private boolean flag = false;



@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.select);

}



/**

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

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

*/

@Override

public void onWindowFocusChanged(boolean hasFocus) {

super.onWindowFocusChanged(hasFocus);

while(!flag){

initWedget();

flag = true;

}



}



/**

* 初始化界面控件

*/

private void initWedget(){

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

handler = new Handler(SelectActivity.this);



//初始化界面组件

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

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

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





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

int width = parent.getWidth();

pwidth = width;



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

image.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

if(flag){

//显示PopupWindow窗口

popupWindwShowing();

}

}

});



//初始化PopupWindow

initPopuWindow();



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

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

button.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

initDatas();

optionsAdapter.notifyDataSetChanged();

}

});

}



/**

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

*/

private void initDatas(){



datas.clear();



datas.add("北京");

datas.add("上海");

datas.add("广州");

datas.add("深圳");

datas.add("重庆");

datas.add("青岛");

datas.add("石家庄");

}



/**

* 初始化PopupWindow

*/

private void initPopuWindow(){



initDatas();



//PopupWindow浮动下拉框布局

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

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



//设置自定义Adapter

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

listView.setAdapter(optionsAdapter);



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



selectPopupWindow.setOutsideTouchable(true);



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

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

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

selectPopupWindow.setBackgroundDrawable(new BitmapDrawable());

}







/**

* 显示PopupWindow窗口

*

* @param popupwindow

*/

public void popupWindwShowing() {

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

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

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

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

}



/**

* PopupWindow消失

*/

public void dismiss(){

selectPopupWindow.dismiss();

}



/**

* 处理Hander消息

*/

@Override

public boolean handleMessage(Message message) {

Bundle data = message.getData();

switch(message.what){

case 1:

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

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

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

dismiss();

break;

case 2:

//移除下拉项数据

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

datas.remove(delIndex);

//刷新下拉列表

optionsAdapter.notifyDataSetChanged();

break;

}

return false;

}

}

自定义适配器Adapter代码:

[java] view
plaincopy

public class OptionsAdapter extends BaseAdapter {



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

private Activity activity = null;

private Handler handler;



/**

* 自定义构造方法

* @param activity

* @param handler

* @param list

*/

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

this.activity = activity;

this.handler = handler;

this.list = list;

}



@Override

public int getCount() {

return list.size();

}



@Override

public Object getItem(int position) {

return list.get(position);

}



@Override

public long getItemId(int position) {

return position;

}



@Override

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

ViewHolder holder = null;

if (convertView == null) {

holder = new ViewHolder();

//下拉项布局

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

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

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



convertView.setTag(holder);

} else {

holder = (ViewHolder) convertView.getTag();

}



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



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

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

@Override

public void onClick(View v) {

Message msg = new Message();

Bundle data = new Bundle();

//设置选中索引

data.putInt("selIndex", position);

msg.setData(data);

msg.what = 1;

//发出消息

handler.sendMessage(msg);

}

});



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

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

@Override

public void onClick(View v) {

Message msg = new Message();

Bundle data = new Bundle();

//设置删除索引

data.putInt("delIndex", position);

msg.setData(data);

msg.what = 2;

//发出消息

handler.sendMessage(msg);

}

});



return convertView;

}



}





class ViewHolder {

TextView textView;

ImageView imageView;

}





主界面布局select.xml文件:

[html] view
plaincopy

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:background="#EEEED1"

>

<LinearLayout android:id="@+id/parent" android:layout_width="wrap_content"

[html] view
plaincopy

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

[html] view
plaincopy

android:layout_marginTop="50dp" android:layout_marginLeft="30dp">

<EditText android:id="@+id/edittext" android:layout_width="200dp" android:singleLine="true"

android:layout_height="40dp" android:background="@drawable/bg1" android:paddingLeft="3dp"/>

<ImageView android:id="@+id/btn_select" android:layout_width="30dp" android:layout_height="40dp"

android:src="@drawable/img1" android:scaleType="fitXY"/>

</LinearLayout>

<Button android:id="@+id/refresh" android:layout_width="wrap_content" android:layout_height="45dp"

android:text="恢复" android:textColor="#000000" android:textSize="20sp"

[html] view
plaincopy

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

lt;/LinearLayout>





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

[html] view
plaincopy

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:gravity="center_horizontal"

>

<ListView android:id="@+id/list" android:layout_width="fill_parent"

android:layout_height="wrap_content" android:cacheColorHint="#00000000">

</ListView>

</LinearLayout>



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

[html] view
plaincopy

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:background="#235654"

>

<RelativeLayout

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:gravity="center_vertical"

android:minHeight="40dp"

>

<ImageView android:id="@+id/delImage" android:layout_width="20dp"

[html] view
plaincopy

android:layout_height="wrap_content" android:src="@drawable/del" android:textSize="18sp"

android:layout_alignParentRight="true" android:layout_marginRight="10dp"/>

<TextView android:id="@+id/item_text" android:layout_height="wrap_content"

android:layout_width="fill_parent" android:layout_toLeftOf="@id/delImage"

android:paddingLeft="5dp" android:layout_alignParentLeft="true"></TextView>

</RelativeLayout>

</LinearLayout>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: