首先看效果

調用方式也非常的簡單如下:
//操作需要用到的圖檔icon
final int itemIconIds[] = new int[] { R.drawable.p_trends_comment,
R.drawable.p_trends_forward, R.drawable.p_trends_share,
R.drawable.p_trends_delete };
final String itemDescs[] = new String[] { "評 論", "轉 發", "共 享",
"删 除" };
//獲得螢幕的高度,設定ListView的最大高度,動态設定ListView的高度
WindowManager windowManager = this.getWindowManager();
Display display = windowManager.getDefaultDisplay();
int screenHeight = display.getHeight();
showBtn = (Button) this.findViewById(R.id.show);
new PathPopupWindowDialog(this, screenHeight, showBtn).create(itemIconIds,
itemDescs,
new ResponseListener());
PathPopupWindowDialog的參數說明:
構造函數中第一個參數“this”是Context,第二個"screenHeight"是螢幕的高度,本來是要根據内容的增加,來不斷調整dialog的高度的,暫時看來是不需要了,第三個參數"showBtn"是用來觸發此dialog的一個按鈕,其實是PopupWindow的showAtLocation需要的parentView
create方法中的參數分别是dialog中每一個item需要的圖示和對應的文字,以及單擊每一個條目需要觸發的事件,内容形式示例如下:
private class ResponseListener implements AdapterView.OnItemClickListener
{
@Override
public void onItemClick(AdapterView<?> adapter, View view, int id,
long position)
{
System.out.println(view + "----");
@SuppressWarnings("unchecked")
HashMap<String, Object> map = (HashMap<String, Object>) adapter.getItemAtPosition((int) position);
Toast.makeText(Android_test_02Activity.this,
map.get("text").toString(),
1000).show();
}
}
其中PathPopupWindowDialog的源碼如下:
package com.king.demo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.content.Context;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager.LayoutParams;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.SimpleAdapter;
/**
* path dialog元件 <br/>
* <br/>
* <b>示例:<br/>
* new PathPopupWindowDialog(Context context, int screenHeight, View showBtn)<br/>
* .create(int itemIconIds[],String itemDescs[],
* AdapterView.OnItemClickListener listener);<br/>
* <br/>
* 參數說明:<br/>
* context ---- 一般是activity<br/>
* screenHeight ---- 螢幕高度<br/>
* showBtn ---- 用來PopupWindow展示,例如Button,點選此button會顯示dialog<br/>
* itemIconIds ---- ListView中每一個item的圖示<br/>
* itemDescs ---- ListView中每一個item的圖示對應的說明<br/>
* listener ---- ListView中每一個item需要響應的操作,需要使用者自己實作。<br/>
* 關于ListView中的值是通過SimpleAdapter設定的,其中SimpleAdapter接收的List<HashMap<String,
* Object>><br/>
* map中存放的key是圖示是"icon"[ITEM_ICON]和文本是"text"[ITEM_TEXT],使用者在實作listener的時候可能需要用到
* </b>
*
* @author kingzhang
*
*/
public class PathPopupWindowDialog
{
public static final String ITEM_ICON = "icon";
public static final String ITEM_TEXT = "text";
/**
* popupWindow
*/
private PopupWindow popupWindow;
/**
* 确定dialog需要的context
*/
private Context context;
/**
* 手機螢幕的高度
*/
private int screenHeight;
/**
* 确定觸發該dialog的view元件,也是建立popupwindow必須的參數
*/
private View parentView;
public PathPopupWindowDialog(Context context, int screenHeight,
View parentView)
{
this.context = context;
this.screenHeight = screenHeight;
this.parentView = parentView;
}
/**
* 建立PopupWindow
*
* @param itemIconIds
* ListView中的圖示
* @param itemDescs
* ListView中圖示對應的描述
* @param responseListener
* 響應listview中的item click listener 事件
*/
public void create(int itemIconIds[], String itemDescs[],
AdapterView.OnItemClickListener responseListener)
{
LayoutInflater inflater = LayoutInflater.from(context);
View popupView = inflater.inflate(R.layout.p_trends_option_popup, null);
//popupView.se
//從popu.xml中獲得其中的元件
ListView listView = (ListView) popupView.findViewById(R.id.path_popupwindow_listview);
//獲得popup中最外層的layout
//LinearLayout linearLayout = (LinearLayout) popupView.findViewById(R.id.p_dynamic_popup_layout);
//設定ListView中的參數屬性
this.setListViewParamters(listView,
itemIconIds,
itemDescs,
responseListener);
//獲得螢幕的高度,設定ListView的最大高度,動态設定ListView的高度
//this.setListViewHeightBasedOnChildren(listView, screenHeight);
//生成PopupWindow對象
popupWindow = new PopupWindow(popupView, LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT, true);
//設定PopupWindow對象需要屬性參數
popupWindow.setAnimationStyle(R.style.path_popwindow_anim_enterorout_window);
popupWindow.setFocusable(true);
popupWindow.setTouchable(true);
//設定popupwindow以外的區域是否可以觸摸
popupWindow.setOutsideTouchable(true);
//顯示popupwindow
parentView.setOnClickListener(new ShowPopupWindowListener());
// 設定android傳回事件,用來隐藏popupwindow
// 不給LinearLayout設定的原因是因為給其加上後,ListView不能獲得焦點
this.setBackListener(listView);
}
/**
* 設定ListView裡面的參數屬性
*
* @param listView
* @param itemIconIds
* ListView中的圖示
* @param itemDescs
* ListView中圖示對應的描述
* @param responseListener
* 響應listview中的item click listener 事件
*/
private void setListViewParamters(ListView listView, int itemIconIds[],
String itemDescs[], AdapterView.OnItemClickListener responseListener)
{
// 給popu.xml中ListView設定值
List<HashMap<String, Object>> itemList = new ArrayList<HashMap<String, Object>>();
for (int i = 0; i < itemDescs.length; i++)
{
HashMap<String, Object> map = new HashMap<String, Object>();
map.put(ITEM_ICON, itemIconIds[i]);
map.put(ITEM_TEXT, itemDescs[i]);
itemList.add(map);
}
SimpleAdapter simpleAdapter = new SimpleAdapter(context, itemList,
R.layout.p_trends_option_popup_item, new String[] { "icon",
"text" }, new int[] { R.id.path_dynamic_popu_item_icon,
R.id.path_dynamic_popu_item_textView });
listView.setFocusable(true);
listView.requestFocus();
listView.setAdapter(simpleAdapter);
listView.setItemsCanFocus(true);
listView.setDividerHeight(0);
//設定ListView中的item點選事件
listView.setOnItemClickListener(responseListener);
}
/**
* 給parentView設定onclicklistener事件,用于顯示popupwindow
*
* @author kingzhang
*
*/
private class ShowPopupWindowListener implements View.OnClickListener
{
@Override
public void onClick(View v)
{
popupWindow.showAtLocation(parentView, Gravity.BOTTOM, 0, 0);
popupWindow.update();
}
}
/**
* 為PopupWindow中的最外層的布局設定onkeylistener事件 用來隐藏彈出的popupwindow
*
* @param layout
* 為PopupWindow中的最外層的布局
* @param pw
* PopupWindow
*/
private void setBackListener(View view)
{
view.setOnKeyListener(new View.OnKeyListener()
{
@Override
public boolean onKey(View v, int keyCode, KeyEvent event)
{
if (event.getAction() == KeyEvent.ACTION_DOWN
&& keyCode == KeyEvent.KEYCODE_BACK)
{
popupWindow.dismiss();
}
return false;
}
});
}
/**
* 動态設定listview的高度
*
* @param listView
* 需要配置的ListView
* @param screenHeight
* 螢幕的高度
* @param imageHeight
* imageHeight
* @param viewHeight
* viewHeight
*/
private void setListViewHeightBasedOnChildren(ListView listView,
int screenHeigh)
{
//擷取ListView對應的Adapter
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null)
{
return;
}
int totalHeight = 0;
for (int i = 0, len = listAdapter.getCount(); i < len; i++)
{
//listAdapter.getCount()傳回資料項的數目
View listItem = listAdapter.getView(i, null, listView);
//計算子項View 的寬高
listItem.measure(0, 0);
//統計所有子項的總高度
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
//listView.getDividerHeight()擷取子項間分隔符占用的高度
int listViewHeight = totalHeight
+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));
//如果總體高度大于螢幕高度,則用螢幕高度
if (listViewHeight > screenHeight)
{
//此處的30是實驗所得出的結果
params.height = screenHeight - 75;
}
//否則設定為計算出來的高度
else
{
params.height = listViewHeight;
}
listView.setLayoutParams(params);
}
}
布局檔案如下:
<?xml version="1.0" encoding="utf-8"?>
<!-- author king -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/p_dynamic_popup_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="30dip">
<!-- 顯示的高度跟這個LinearLayout的background的大小有關,以及和item裡面的backgroud有關 -->
<!-- 用來顯示popupwindow中的清單項 -->
<ImageView
android:id="@+id/title_bg"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:src="@drawable/top"
android:scaleType="fitXY"/>
<ListView
android:id="@+id/path_popupwindow_listview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:background="@drawable/bg"
android:cacheColorHint="#00000000"/>
<ImageView
android:id="@+id/bottom_bg"
android:src="@drawable/bottom"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"/>
</LinearLayout>
和
<?xml version="1.0" encoding="utf-8"?>
<!-- author king -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="60dip"
android:gravity="center"
android:orientation="horizontal" >
<ImageView
android:id="@+id/path_dynamic_popu_item_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:scaleType="centerInside"/>
<TextView
android:id="@+id/path_dynamic_popu_item_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="10dip"
android:gravity="center"
android:textColor="@android:color/white"
android:textSize="22sp"/>
</LinearLayout>
剩下的就是所用的圖檔背景如下:
用到的動畫效果的xml檔案如下:
enter window
<?xml version="1.0" encoding="utf-8"?>
<!-- author king -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator" >
<translate
android:duration="300"
android:fromXDelta="0.0"
android:fromYDelta="100%"
android:toXDelta="0.0"
android:toYDelta="0.0" />
</set>
out window
<?xml version="1.0" encoding="utf-8"?>
<!-- author king -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator">
<translate
android:duration="400"
android:fromXDelta="0.0"
android:fromYDelta="0.0"
android:toXDelta="0.0"
android:toYDelta="100%" />
</set>
style檔案外為:
<?xml version="1.0" encoding="utf-8"?>
<!-- author king -->
<resources>
<style name="path_popwindow_anim_enterorout_window">
<item name="android:windowEnterAnimation">@anim/p_trends_enter_window</item>
<!-- 指定顯示的動畫xml -->
<item name="android:windowExitAnimation">@anim/p_trends_out_window</item>
<!-- 指定消失的動畫xml -->
</style>
</resources>