天天看點

Android實作仿QQ登入可編輯下拉菜單

在android裡,直接提供的spinner控件雖然可以實作下拉菜單的效果,但其效果并不理想,很多時候我們需要類似手機qq那樣既可以在文本框中直接輸入編輯文字,可以在下拉菜單中選中或者删除菜單選項,并且下拉菜單并不是以遮罩整個手機螢幕方式,而是以浮動在螢幕上的效果出現。下面呢,就來實作一下這些效果。

最後效果為:

Android實作仿QQ登入可編輯下拉菜單
Android實作仿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方法中是無法擷取到該寬度的  

     */  

    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() {  

                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消息  

    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);  

                //重新整理下拉清單  

        return false;  

}  

自定義擴充卡adapter代碼:

[java] view

public class optionsadapter extends baseadapter {  

    private arraylist<string> list = new arraylist<string>();   

    private activity activity = null;   

    /** 

     * 自定義構造方法 

     * @param activity 

     * @param handler 

     * @param list 

    public optionsadapter(activity activity,handler handler,arraylist<string> list){  

        this.activity = activity;  

        this.handler = handler;  

        this.list = list;  

    public int getcount() {  

        return list.size();  

    public object getitem(int position) {  

        return list.get(position);  

    public long getitemid(int position) {  

        return position;  

    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() {  

                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() {  

                //設定删除索引  

                data.putint("delindex", position);  

                msg.what = 2;  

        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="恢複" android:textcolor="#000000" android:textsize="20sp"   

android:layout_margintop="30dp" android:layout_marginleft="30dp"/>  

lt;/linearlayout>  

popupwindow浮動下拉框布局options.xml檔案:

    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>  

下拉選項布局option_item.xml檔案:

    android:background="#235654"  

<relativelayout  

    android:layout_width="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>  

繼續閱讀