Android实现可编辑下拉菜单
Android實(shí)現(xiàn)仿QQ登錄可編輯下拉菜單
在Android里,直接提供的Spinner控件雖然可以實(shí)現(xiàn)下拉菜單的效果,但其效果并不理想,很多時(shí)候我們需要類似手機(jī)QQ那樣既可以在文本框中直接輸入編輯文字,可以在下拉菜單中選中或者刪除菜單選項(xiàng),并且下拉菜單并不是以遮罩整個(gè)手機(jī)屏幕方式,而是以浮動(dòng)在屏幕上的效果出現(xiàn)。下面呢,就來實(shí)現(xiàn)一下這些效果。
此次主要以EdiText、PopupWindow、ListView及Adapter來實(shí)現(xiàn)這種下拉效果。具體實(shí)現(xiàn)步驟就不一步步詳細(xì)介紹了,直接貼完整代碼吧,注釋比較詳細(xì),相信都能看得懂。
?
Activity代碼:
package com.zw.select;
import java.util.ArrayList;
import android.app.Activity;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.ListView;
import android.widget.PopupWindow;
?
//主界面Activity
public class SelectActivity extends Activity implements Callback {
??? //PopupWindow對(duì)象
??? private PopupWindow selectPopupWindow= null;
??? //自定義Adapter
??? private OptionsAdapteroptionsAdapter = null;
??? //下拉框選項(xiàng)數(shù)據(jù)源
??? private ArrayList<String> datas = new ArrayList<String>();;
??? //下拉框依附組件
??? private LinearLayout parent;
??? //下拉框依附組件寬度,也將作為下拉框的寬度
??? private int pwidth;
??? //文本框
??? private EditText et;
??? //下拉箭頭圖片組件
??? private ImageView image;
??? //恢復(fù)數(shù)據(jù)源按鈕
??? private Button button;
??? //展示所有下拉選項(xiàng)的ListView
??? private ListView listView = null;
??? //用來處理選中或者刪除下拉項(xiàng)消息
??? private Handler handler;
??? //是否初始化完成標(biāo)志?
??? private boolean flag = false;
???
??? @Override
??? public void onCreate(Bundle savedInstanceState) {
??????? super.onCreate(savedInstanceState);
??????? setContentView(R.layout.select);
??? }
?
??? /**
???? * 沒有在onCreate方法中調(diào)用initWedget(),而是在onWindowFocusChanged方法中調(diào)用,
???? * 是因?yàn)?/span>initWedget()中需要獲取PopupWindow浮動(dòng)下拉框依附的組件寬度,在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;
???????
??????? //設(shè)置點(diǎn)擊下拉箭頭圖片事件,點(diǎn)擊彈出PopupWindow浮動(dòng)下拉框
??????? image.setOnClickListener(newView.OnClickListener() {
?????????? @Override
?????????? public void onClick(View v) {
????????????? if(flag){
????????????????? //顯示PopupWindow窗口
????????????????? popupWindwShowing();
????????????? }
?????????? }
?????? });
???????
??????? //初始化PopupWindow
??????? initPopuWindow();
???????
??????? button = (Button)findViewById(R.id.refresh);
??????? //設(shè)置點(diǎn)擊事件,恢復(fù)下拉框列表數(shù)據(jù),沒有什么作用,純粹是為了方便多看幾次效果而設(shè)置
?????? button.setOnClickListener(new View.OnClickListener() {
?????????? @Override
?????????? public void onClick(View v) {
????????????? initDatas();
????????????? optionsAdapter.notifyDataSetChanged();
?????????? }
?????? });
??? }
?
??? /**
??? ?* 初始化填充Adapter所用List數(shù)據(jù)
??? ?*/
??? 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浮動(dòng)下拉框布局
??????? View loginwindow = (View)this.getLayoutInflater().inflate(R.layout.options, null);
??????? listView = (ListView) loginwindow.findViewById(R.id.list);
???????
??????? //設(shè)置自定義Adapter
??????? optionsAdapter = new OptionsAdapter(this, handler,datas);
??????? listView.setAdapter(optionsAdapter);
???????
??????? selectPopupWindow = new PopupWindow(loginwindow,pwidth,LayoutParams.WRAP_CONTENT, true);
???????
??????? selectPopupWindow.setOutsideTouchable(true);
???????
??????? //這一句是為了實(shí)現(xiàn)彈出PopupWindow后,當(dāng)點(diǎn)擊屏幕其他部分及Back鍵時(shí)PopupWindow會(huì)消失,
??????? //沒有這一句則效果不能出來,但并不會(huì)影響背景
??????? //本人能力極其有限,不明白其原因,還望高手、知情者指點(diǎn)一下
??????? selectPopupWindow.setBackgroundDrawable(newBitmapDrawable());?
??? }
?
???
???
??? /**
???? * 顯示PopupWindow窗口
???? *
???? * @param popupwindow
???? */
??? public void popupWindwShowing() {
?????? //將selectPopupWindow作為parent的下拉框顯示,并指定selectPopupWindow在Y方向上向上偏移3pix,
?????? //這是為了防止下拉框與文本框之間產(chǎn)生縫隙,影響界面美化
?????? //(是否會(huì)產(chǎn)生縫隙,及產(chǎn)生縫隙的大小,可能會(huì)根據(jù)機(jī)型、Android系統(tǒng)版本不同而異吧,不太清楚)
?????? 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:
????????????? //選中下拉項(xiàng),下拉框消失
????????????? int selIndex = data.getInt("selIndex");
????????????? et.setText(datas.get(selIndex));
????????????? dismiss();
????????????? break;
?????????? case 2:
????????????? //移除下拉項(xiàng)數(shù)據(jù)
????????????? int delIndex = data.getInt("delIndex");
????????????? datas.remove(delIndex);
????????????? //刷新下拉列表
????????????? optionsAdapter.notifyDataSetChanged();
????????????? break;
?????? }
?????? return false;
??? }
}
?
?
?
自定義適配器Adapter代碼:
package com.zw.select;
?
import java.util.ArrayList;
?
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
?
//自定義適配器Adapter
public class OptionsAdapter extends BaseAdapter {
?
??? private ArrayList<String> list = new ArrayList<String>();
? ??private Activity activity = null;
??? private Handler handler;
???
??? /**
??? ?* 自定義構(gòu)造方法
??? ?* @param activity
??? ?* @param handler
??? ?* @param list
??? ?*/
??? public OptionsAdapter(Activityactivity,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();
??????????? //下拉項(xiàng)布局
??????????? 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));
???????
??????? //為下拉框選項(xiàng)文字部分設(shè)置事件,最終效果是點(diǎn)擊將其文字填充到文本框
??????? holder.textView.setOnClickListener(newView.OnClickListener() {
?????????? @Override
?????????? public void onClick(View v) {
????????????? Message msg = new Message();
????????????? Bundle data = new Bundle();
????????????? //設(shè)置選中索引
????????????? data.putInt("selIndex", position);
????????????? msg.setData(data);
????????????? msg.what = 1;
????????????? //發(fā)出消息
????????????? handler.sendMessage(msg);
?????????? }
?????? });
???????
??????? //為下拉框選項(xiàng)刪除圖標(biāo)部分設(shè)置事件,最終效果是點(diǎn)擊將該選項(xiàng)刪除
??????? holder.imageView.setOnClickListener(newView.OnClickListener() {
?????????? @Override
?????????? public void onClick(View v) {
????????????? Message msg = new Message();
????????????? Bundle data = new Bundle();
????????????? //設(shè)置刪除索引
????????????? data.putInt("delIndex", position);
????????????? msg.setData(data);
????????????? msg.what = 2;
????????????? //發(fā)出消息
????????????? handler.sendMessage(msg);
?????????? }
?????? });
???????
??????? return convertView;
??? }
?
}
?
?
class ViewHolder {
??? TextView textView;
??? ImageView imageView;
}
?
?
?
?
主界面布局select.xml文件:
<?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" android:layout_height="wrap_content"
??? ?android:orientation="horizontal"? 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="恢復(fù)" android:textColor="#000000"android:textSize="20sp" android:layout_marginTop="30dp"
??? android:layout_marginLeft="30dp"/>
</LinearLayout>
?
?
?
PopupWindow浮動(dòng)下拉框布局options.xml文件:
?
<?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>
?
?
?
下拉選項(xiàng)布局option_item.xml文件:
<?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" 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>
?
?
?
?
?
到此代碼及布局文件基本都貼完了。
?
?
總結(jié)
以上是生活随笔為你收集整理的Android实现可编辑下拉菜单的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深造分布式 打败面试官 招式三 直捣黄龙
- 下一篇: POST /product/:id 获取