首先看效果
调用方式也非常的简单如下:
//操作需要用到的图片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>