Android利用PopupWindow实现点击工具栏弹出下拉菜单
jopen
10年前
1.概述
本文将介绍如何利用PopupWindow实现点击屏幕顶部工具栏按钮弹出下拉菜单的功能。先上图:
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>
3.工程源码
来自:http://blog.csdn.net/chadeltu/article/details/43487551