Android的对话框有两种:PopupWindow和AlertDialog。它们的不同点在于:
AlertDialog的位置固定,而PopupWindow的位置可以随意

AlertDialog是非阻塞线程的,而PopupWindow是阻塞线程的

PopupWindow的位置按照有无偏移分,可以分为偏移和无偏移两种;按照参照物的不同,可以分为相对于某个控件(Anchor锚)和相对于父控件。具体如下
showAsDropDown(View anchor):相对某个控件的位置(正左下方),无偏移
showAsDropDown(View anchor, int xoff, int yoff):相对某个控件的位置,有偏移
showAtLocation(View parent, int gravity, int x, int y):相对于父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以设置偏移或无偏移

项目目录结构和效果图

1.PopupWindow的布局,里面只有一个ListView

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"> <ListView
android:id="@+id/popupwindow"
android:background="@drawable/mm_title_functionframe"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:divider="@drawable/mm_title_functionframe_line"
android:listSelector="@drawable/mm_title_functionframe_pressed"
android:cacheColorHint="@android:color/transparent">
</ListView>
</RelativeLayout>

2.PopupWindow item的布局,为了简单起里面只有一个TextView

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="8.0dip" > <TextView
android:id="@+id/popup_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:singleLine="true"
android:ellipsize="end"
android:textColor="#ffffffff"/> </RelativeLayout>

3.写一个PopupWindow的派生类,这里我直接贴代码,注释还是比较详细,只有用了一个回调接口,不明白回调函数的看这里 http://blog.csdn.net/xiaanming/article/details/8703708

package com.example.popupwindow;

import java.util.ArrayList;
import java.util.List; import android.content.Context;
import android.graphics.drawable.BitmapDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.PopupWindow; /**
*
* @author xiaanming
*
*/
public class MtitlePopupWindow extends PopupWindow {
/**
* 上下文对象
*/
private Context mContext;
/**
* 回调接口对象
*/
private OnPopupWindowClickListener listener;
/**
* ArrayAdapter对象
*/
private ArrayAdapter adapter;
/**
* ListView的数据源
*/
private List<String> list = new ArrayList<String>();
/**
* PopupWindow的宽度
*/
private int width = 0; public MtitlePopupWindow(Context context){
super(context);
mContext = context;
initView();
} private void initView(){
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View popupView = inflater.inflate(R.layout.title_popupwindow, null);
setContentView(popupView); //设置宽度,若没有设置宽度为LayoutParams.WRAP_CONTENT
setWidth(250);
setHeight(LayoutParams.WRAP_CONTENT); //设置动画,也可以不设置。不设置则是显示默认的
setAnimationStyle(R.style.popupwindow_animation); //这里很重要,不设置这个ListView得不到相应
this.setFocusable(true);
this.setBackgroundDrawable(new BitmapDrawable());
this.setOutsideTouchable(true); ListView listView = (ListView) popupView.findViewById(R.id.popupwindow);
adapter = new ArrayAdapter(mContext, R.layout.popupwindow_item, R.id.popup_item, list);
listView.setAdapter(adapter); //ListView的点击事件
listView.setOnItemClickListener(new OnItemClickListener() { @Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
MtitlePopupWindow.this.dismiss();
if(listener != null){
listener.onPopupWindowItemClick(position);
}
}
}); } /**
* 为PopupWindow设置回调接口
* @param listener
*/
public void setOnPopupWindowClickListener(OnPopupWindowClickListener listener){
this.listener = listener;
} /**
* 设置数据的方法,供外部调用
* @param mList
*/
public void changeData(List<String> mList) {
//这里用addAll也很重要,如果用this.list = mList,调用notifyDataSetChanged()无效
//notifyDataSetChanged()数据源发生改变的时候调用的,this.list = mList,list并没有发生改变
list.addAll(mList);
adapter.notifyDataSetChanged();
} /**
* 回调接口.供外部调用
* @author xiaanming
*
*/
public interface OnPopupWindowClickListener{
/**
* 当点击PopupWindow的ListView 的item的时候调用此方法,用回调方法的好处就是降低耦合性
* @param position 位置
*/
void onPopupWindowItemClick(int position);
} }

上面还用到了动画,比较简单的动画,不太懂动画请到这里http://blog.csdn.net/xiaanming/article/details/8997260

popupwindow_enter

<?xml version="1.0" encoding="UTF-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="100%p"
android:toXDelta="0"
android:duration="500"/>
</set>

popupwindow_exit

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="0"
android:toXDelta="100%p"
android:duration="500"/>
</set>
<resources>
<style name="popupwindow_animation">
<item name="android:windowEnterAnimation">@anim/popupwindow_enter</item>
<item name="android:windowExitAnimation">@anim/popupwindow_exit</item>
</style> </resources>

这样子,以后我们遇到类似的popupwindow的就可以复用了,接下来我们看使用吧,使用很简单,布局里面一个Button,点击Button弹出一个PopupWindow,直接看代码吧

package com.example.popupwindow;

import java.util.Arrays;

import com.example.popupwindow.MtitlePopupWindow.OnPopupWindowClickListener;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast; public class PopupActivity extends Activity {
MtitlePopupWindow mtitlePopupWindow;
String [] items = {"刷新列表", "修改密码", "系统设置", "添加用户", "关于"}; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); Button mButton = (Button) findViewById(R.id.button1);
mButton.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
mtitlePopupWindow.showAsDropDown(v);
}
}); mtitlePopupWindow = new MtitlePopupWindow(this);
mtitlePopupWindow.changeData(Arrays.asList(items));
mtitlePopupWindow.setOnPopupWindowClickListener(new OnPopupWindowClickListener() { @Override
public void onPopupWindowItemClick(int position) {
//你要做的事
Toast.makeText(getApplication(), items[position], Toast.LENGTH_SHORT).show();
}
});
} }

总体来说就是这样子,P opupWindow的使用还是挺简单的,这是小弟的一点拙见,写的不好的地方还请大神指出!

项目下载

PopupWindow的使用以及ArrayAdatper.notifyDataSetChanged()无效详解的更多相关文章

  1. Android PopupWindow Dialog 关于 is your activity running 崩溃详解

    Android PopupWindow Dialog 关于 is your activity running 崩溃详解 [TOC] 起因 对于 PopupWindow Dialog 需要 Activi ...

  2. Dialog详解(包括进度条、PopupWindow、自定义view、自定义样式的对话框)

    Dialog详解(包括进度条.PopupWindow.自定义view.自定义样式的对话框)   Android中提供了多种对话框,在实际应用中我们可能会需要修改这些已有的对话框.本实例就是从实际出发, ...

  3. Android 关于ListView中adapter调用notifyDataSetChanged无效的原因

    话说这个问题已经困扰我很久了,一直找不到原因,我以为只要数据变了,调用adapter的notifyDataSetChanged就会更新列表,最近在做微博帐号管理这一块,想着动态更新列表,数据是变了,但 ...

  4. Android开发之关于ListView中adapter调用notifyDataSetChanged无效的原因

    1.数据源没有更新,调用notifyDataSetChanged无效. 2.数据源更新了,但是它指向新的引用,调用notifyDataSetChanged无效. 3.数据源更新了,但是adpter没有 ...

  5. BaseAdapter导致notifyDataSetChanged()无效的四个原因及处理方法

    前一段时间在做一个项目的时候遇到了一个关于BaseAdapter的notifyDataSetChanged()方法无效问题,当时在网上搜了一个解决方法,今天又遇到了一个类似的问题,我在这里做个记录,防 ...

  6. PopUpWindow使用详解(二)——进阶及答疑

      相关文章:1.<PopUpWindow使用详解(一)——基本使用>2.<PopUpWindow使用详解(二)——进阶及答疑> 上篇为大家基本讲述了有关PopupWindow ...

  7. Android RecyclerView遇到notifyDataSetChanged无效时的解决方案

    一.简述 不管AbsListView(ListView.GridView)或是新出的RecyclerView,在使用notifyDataSetChanged方法更新列表数据时,一定要保证数据为同个对象 ...

  8. Android Notification 详解(一)——基本操作

    Android Notification 详解(一)--基本操作 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Notification 文中如有纰 ...

  9. Android Notification 详解——基本操作

    Android Notification 详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 前几天项目中有用到 Android 通知相关的内容,索性把 Android Notificatio ...

随机推荐

  1. HDU 1584 蜘蛛牌

    题解:纸牌只能移到比其大一的纸牌上,所以移动方向是定的,那么,就只有选择移动先后的问题了,对于决定要移的纸牌,比如1,如果2,3,4都是visited的状态,那么1一定是要移动到5的,因为2,3,4一 ...

  2. PLSQL 导入表到Oracle------》从一个表空间导入到其它表空间

        在用PLSQL导入.dmp文件到Oracle时出现的问题如下: Import started on 2015/11/18 10:42:44E:\oracle\product\10.2.0\db ...

  3. java实现字符串匹配问题之求两个字符串的最大公共子串

    转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/38924981 近期在项目工作中有一个关于文本对照的需求,经过这段时间的学习,总结 ...

  4. [Asp.net]常见word,excel,ppt,pdf在线预览方案(转)

    引言 之前项目需要,查找了office文档在线预览的解决方案,顺便记录一下,方便以后查询. 方案一 直接在浏览器中打开Office文档在页面上的链接.会弹出如下窗口: 优点:主流浏览器都支持. 缺点: ...

  5. ASP.NET常用内置对象

    ASP.NET 常用内置对象:Response对象.Request对象.Session对象.Server对象.Application对象 1.Response对象: (1) 用于向浏览器输出信息 常用 ...

  6. 语句(语句分类及if语句)

    目前为止,之前学过的程序只能一句一句向下执行.C#:选择控制:if,else,switch,case循环控制:while,do,for,foreach跳转语句:break,continue异常处理:t ...

  7. JavaSE学习总结第18天_集合框架4

      18.01 Map集合概述和特点 Map接口概述:将键映射到值的对象,一个映射不能包含重复的键,每个键最多只能映射到一个值 Map接口和Collection接口的不同 1.Map是双列的,Coll ...

  8. BZOJ 1692: [Usaco2007 Dec]队列变换( 贪心 )

    数据 n <= 30000 , 然后 O( n² ) 的贪心也过了..... USACO 数据是有多弱啊 = = ( ps : BZOJ 1640 和此题一模一样 , 双倍经验 ) ------ ...

  9. python中的map,filter,zip函数

    map() Return an iterator that applies function to every item of iterable, yielding the results 例如: a ...

  10. 部署django - Apache + mod_wsgi + windows

    部署django - Apache + mod_wsgi + windows 1.环境 django 1.6.2 python 3.3 32位 apache 2.4.7 32位 一个可以使用的djan ...