Android利用PopupWindow实现点击工具栏弹出下拉菜单

jopen 10年前

1.概述

本文将介绍如何利用PopupWindow实现点击屏幕顶部工具栏按钮弹出下拉菜单的功能。先上图:

图1图2


图3图4


图5图6

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="#897D13"      tools:context=".MainActivity" >        <RelativeLayout          android:id="@+id/rl_topbar"          android:layout_width="match_parent"          android:layout_height="40dip"          android:background="#BF7F40"          android:gravity="center_vertical" >            <TextView              android:id="@+id/tv_left"              android:layout_width="70dip"              android:layout_height="30dip"              android:layout_alignParentLeft="true"              android:layout_marginLeft="10dip"              android:background="@drawable/btn_selector_pop"              android:clickable="true"              android:gravity="center"              android:text="left"              android:textColor="@android:color/white"              android:textSize="16sp" />            <TextView              android:id="@+id/tv_middle"              android:layout_width="70dip"              android:layout_height="30dip"              android:layout_centerHorizontal="true"              android:background="@drawable/btn_selector_pop"              android:clickable="true"              android:gravity="center"              android:text="middle"              android:textColor="@android:color/white"              android:textSize="16sp" />            <TextView              android:id="@+id/tv_right"              android:layout_width="70dip"              android:layout_height="30dip"              android:layout_alignParentRight="true"              android:layout_marginRight="10dip"              android:background="@drawable/btn_selector_pop"              android:clickable="true"              android:gravity="center"              android:text="right"              android:textColor="@android:color/white"              android:textSize="16sp" />      </RelativeLayout>        <TextView          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:layout_centerInParent="true"          android:text="Drop-down Menu"          android:textColor="@android:color/white"          android:textSize="20sp" />    </RelativeLayout>
其中,rl_topbar定义了顶部工具栏,里面包含左中右三个TextView,点击这三个控件会弹出相应的下拉菜单。

接下来是MainActivity.java文件: </div>
package com.example.dropdownmenu;    import java.util.ArrayList;  import java.util.HashMap;  import java.util.List;  import java.util.Map;    import android.os.Bundle;  import android.app.Activity;  import android.graphics.drawable.ColorDrawable;  import android.view.Menu;  import android.view.MotionEvent;  import android.view.View;  import android.view.ViewGroup.LayoutParams;  import android.widget.AdapterView;  import android.widget.ListView;  import android.widget.PopupWindow;  import android.widget.RelativeLayout;  import android.widget.SimpleAdapter;  import android.widget.TextView;    public class MainActivity extends Activity {     // 工具栏   private RelativeLayout rlTopBar;     // 左中右三个控件(工具栏里)   private TextView tvLeft;   private TextView tvRight;   private TextView tvMiddle;     // 左中右三个弹出窗口   private PopupWindow popLeft;   private PopupWindow popRight;   private PopupWindow popMiddle;     // 左中右三个layout   private View layoutLeft;   private View layoutRight;   private View layoutMiddle;     // 左中右三个ListView控件(弹出窗口里)   private ListView menulistLeft;   private ListView menulistRight;   private ListView menulistMiddle;     // 菜单数据项   private List<Map<String, String>> listLeft;   private List<Map<String, String>> listRight;   private List<Map<String, String>> listMiddle;     @Override   protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);      initParam();   }     private void initParam() {    rlTopBar = (RelativeLayout) this.findViewById(R.id.rl_topbar);      tvLeft = (TextView) this.findViewById(R.id.tv_left);    tvLeft.setOnClickListener(myListener);    // 初始化数据项    listLeft = new ArrayList<Map<String, String>>();    for (int i = 1; i < 10; i++) {     HashMap<String, String> mapTemp = new HashMap<String, String>();     mapTemp.put("item", "left " + i);     listLeft.add(mapTemp);    }      tvRight = (TextView) this.findViewById(R.id.tv_right);    tvRight.setOnClickListener(myListener);    // 初始化数据项    listRight = new ArrayList<Map<String, String>>();    for (int i = 1; i < 10; i++) {     HashMap<String, String> mapTemp = new HashMap<String, String>();     mapTemp.put("item", "right " + i);     listRight.add(mapTemp);    }      tvMiddle = (TextView) this.findViewById(R.id.tv_middle);    tvMiddle.setOnClickListener(myListener);    // 初始化数据项    listMiddle = new ArrayList<Map<String, String>>();    for (int i = 1; i < 10; i++) {     HashMap<String, String> mapTemp = new HashMap<String, String>();     mapTemp.put("item", "mid " + i);     listMiddle.add(mapTemp);    }   }     private View.OnClickListener myListener = new View.OnClickListener() {      @Override    public void onClick(View v) {     switch (v.getId()) {     case R.id.tv_left:      if (popLeft != null && popLeft.isShowing()) {       popLeft.dismiss();      } else {       layoutLeft = getLayoutInflater().inflate(         R.layout.pop_menulist, null);       menulistLeft = (ListView) layoutLeft         .findViewById(R.id.menulist);       SimpleAdapter listAdapter = new SimpleAdapter(         MainActivity.this, listLeft, R.layout.pop_menuitem,         new String[] { "item" },         new int[] { R.id.menuitem });       menulistLeft.setAdapter(listAdapter);         // 点击listview中item的处理       menulistLeft         .setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override          public void onItemClick(AdapterView<?> arg0,            View arg1, int arg2, long arg3) {           // 改变顶部对应TextView值           String strItem = listLeft.get(arg2).get(            "item");           tvLeft.setText(strItem);                      // 隐藏弹出窗口           if (popLeft != null && popLeft.isShowing()) {            popLeft.dismiss();           }          }         });         // 创建弹出窗口       // 窗口内容为layoutLeft,里面包含一个ListView       // 窗口宽度跟tvLeft一样       popLeft = new PopupWindow(layoutLeft, tvLeft.getWidth(),         LayoutParams.WRAP_CONTENT);         ColorDrawable cd = new ColorDrawable(-0000);       popLeft.setBackgroundDrawable(cd);       popLeft.setAnimationStyle(R.style.PopupAnimation);       popLeft.update();       popLeft.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);       popLeft.setTouchable(true); // 设置popupwindow可点击       popLeft.setOutsideTouchable(true); // 设置popupwindow外部可点击       popLeft.setFocusable(true); // 获取焦点         // 设置popupwindow的位置(相对tvLeft的位置)       int topBarHeight = rlTopBar.getBottom();       popLeft.showAsDropDown(tvLeft, 0,         (topBarHeight - tvLeft.getHeight()) / 2);         popLeft.setTouchInterceptor(new View.OnTouchListener() {          @Override        public boolean onTouch(View v, MotionEvent event) {         // 如果点击了popupwindow的外部,popupwindow也会消失         if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {          popLeft.dismiss();          return true;         }         return false;        }       });      }      break;     case R.id.tv_right:      if (popRight != null && popRight.isShowing()) {       popRight.dismiss();      } else {       layoutRight = getLayoutInflater().inflate(         R.layout.pop_menulist, null);       menulistRight = (ListView) layoutRight         .findViewById(R.id.menulist);       SimpleAdapter listAdapter = new SimpleAdapter(         MainActivity.this, listRight, R.layout.pop_menuitem,         new String[] { "item" },         new int[] { R.id.menuitem });       menulistRight.setAdapter(listAdapter);         // 点击listview中item的处理       menulistRight         .setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override          public void onItemClick(AdapterView<?> arg0,            View arg1, int arg2, long arg3) {           String strItem = listRight.get(arg2).get(            "item");           tvRight.setText(strItem);                      if (popRight != null && popRight.isShowing()) {            popRight.dismiss();           }          }         });         popRight = new PopupWindow(layoutRight, tvRight.getWidth(),         LayoutParams.WRAP_CONTENT);         ColorDrawable cd = new ColorDrawable(-0000);       popRight.setBackgroundDrawable(cd);       popRight.setAnimationStyle(R.style.PopupAnimation);       popRight.update();       popRight.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);       popRight.setTouchable(true); // 设置popupwindow可点击       popRight.setOutsideTouchable(true); // 设置popupwindow外部可点击       popRight.setFocusable(true); // 获取焦点         // 设置popupwindow的位置       int topBarHeight = rlTopBar.getBottom();       popRight.showAsDropDown(tvRight, 0,         (topBarHeight - tvRight.getHeight()) / 2);         popRight.setTouchInterceptor(new View.OnTouchListener() {          @Override        public boolean onTouch(View v, MotionEvent event) {         // 如果点击了popupwindow的外部,popupwindow也会消失         if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {          popRight.dismiss();          return true;         }         return false;        }       });      }      break;     case R.id.tv_middle:      if (popMiddle != null && popMiddle.isShowing()) {       popMiddle.dismiss();      } else {       layoutMiddle = getLayoutInflater().inflate(         R.layout.pop_menulist, null);       menulistMiddle = (ListView) layoutMiddle         .findViewById(R.id.menulist);       SimpleAdapter listAdapter = new SimpleAdapter(         MainActivity.this, listMiddle, R.layout.pop_menuitem,         new String[] { "item" },         new int[] { R.id.menuitem });       menulistMiddle.setAdapter(listAdapter);         // 点击listview中item的处理       menulistMiddle         .setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override          public void onItemClick(AdapterView<?> arg0,            View arg1, int arg2, long arg3) {           String strItem = listMiddle.get(arg2).get(            "item");           tvMiddle.setText(strItem);                      if (popMiddle != null && popMiddle.isShowing()) {            popMiddle.dismiss();           }          }         });         popMiddle = new PopupWindow(layoutMiddle, tvMiddle.getWidth(),         LayoutParams.WRAP_CONTENT);         ColorDrawable cd = new ColorDrawable(-0000);       popMiddle.setBackgroundDrawable(cd);       popMiddle.setAnimationStyle(R.style.PopupAnimation);       popMiddle.update();       popMiddle.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);       popMiddle.setTouchable(true); // 设置popupwindow可点击       popMiddle.setOutsideTouchable(true); // 设置popupwindow外部可点击       popMiddle.setFocusable(true); // 获取焦点         // 设置popupwindow的位置       int topBarHeight = rlTopBar.getBottom();       popMiddle.showAsDropDown(tvMiddle, 0,         (topBarHeight - tvMiddle.getHeight()) / 2);         popMiddle.setTouchInterceptor(new View.OnTouchListener() {          @Override        public boolean onTouch(View v, MotionEvent event) {         // 如果点击了popupwindow的外部,popupwindow也会消失         if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {          popMiddle.dismiss();          return true;         }         return false;        }       });      }      break;     default:      break;     }    }     };     @Override   public boolean onCreateOptionsMenu(Menu menu) {    // Inflate the menu; this adds items to the action bar if it is present.    getMenuInflater().inflate(R.menu.activity_main, menu);    return true;   }    }

以上代码有详细的注释,这里就不做过多解释啦!原理比较简单,点击工具栏上的TextView会弹出PopupWindow,里面包含ListView,显示所有菜单项。

弹出的菜单窗口(PopupWindow)布局文件为pop_menulist.xml,就一个ListView
<?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="wrap_content"      android:background="@drawable/shape_bg_pop"      android:orientation="vertical"      >      <ListView          android:id="@+id/menulist"          android:layout_width="fill_parent"          android:layout_height="wrap_content"          android:divider="#696969"          android:dividerHeight="1.0dip"          android:padding="2dip"          android:scrollbars="none" >      </ListView>  </LinearLayout>

而每个菜单项对应的布局文件为pop_menuitem.xml,只包含一个TextView
<?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="wrap_content"      android:orientation="horizontal"      android:background="@drawable/bg_list_item_pop" >      <TextView          android:id="@+id/menuitem"          android:layout_width="fill_parent"          android:layout_height="wrap_content"          android:textColor="@android:color/white"          android:padding="10dip"          android:textSize="16sp" />  </LinearLayout>

其他还有一些属性资源相关的文件,不是很重要,大家可以下载工程源码进行研究! </div>

3.工程源码




来自:http://blog.csdn.net/chadeltu/article/details/43487551