Android PopupWindow和AlertDialog学习笔记

Android的对话框有两种:PopupWindow和AlertDialog。 详细说明如下: AlertDialog是非阻塞式对话框:AlertDialog弹出时,后台还可以做事情; AlertDialog的位置固定,而PopupWindow的位置可以随意; AlertDialog弹出时,背景是黑色的,但是当我们点击背景,AlertDialog会消失,证明程序不仅响应AlertDialog的操作,还响应其他操作,其他程序没有被阻塞,这说明了AlertDialog是非阻塞式对话框; PopupWindow是阻塞式对话框:PopupWindow弹出时,程序会等待,在PopupWindow退出前,程序一直等待,只有当我们调用了dismiss方法的后,PopupWindow退出,程序才会向下执行。 PopupWindow的位置按照有无偏移分,可以分为偏移和无偏移两种;按照参照物的不同,可以分为相对于某个控件(Anchor锚)和相对于父控件; PopupWindow弹出时,背景没有什么变化,但是当我们点击背景的时候,程序没有响应,只允许我们操作PopupWindow,其他操作被阻塞。

显示PopupWindow的方式:

1.showAsDropDown(View anchor):相对某个控件的位置(正左下方),无偏移。
2.showAsDropDown(View anchor, int xoff, int yoff):相对某个控件的位置,有偏移。
3.showAtLocation(View parent, int gravity, int x, int y):相对于父控件的位置,可以设置偏移或无偏移。

PopupWindow几种普通方法的说明:
1.popupWindow.setAnimationStyle(R.style.PopupAnimation); //可以设置动画。
2.new PopupWindow(view,ViewGroup.LayoutParams.FILL_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);//在构造函数中可以设置popupwindow的大小。
3.当有 popuWindow.setFocusable(false);的时候,说明 PopuWindow不能获得焦点,即使设置了背景不为空也不能点击外面消失,只能由 dismiss()消失,但是外面的 View的事件还是可以触发,back键也可以顺利dismiss掉。当设置为 popuWindow.setFocusable(true);的时候,系统会捕获到焦点给popupWindow,设置此参数获得焦点,否则无法点击。注意要加上设置背景代码,点击外面和Back键才会消失。

PopupWindow详细请看代码:

public static PopupWindow initPopWindow(Context context,int resource) {		
	// 加载popupWindow的布局文件 
	View contentView = LayoutInflater.from(context).inflate(resource, null);
	
	//创建一个PopupWindow实例
	//创建的时候可以设置布局,可以设置高宽,可以设置是否可以获取焦点
	//Note:如果设置LayoutParams.WRAP_CONTENT,getWidth获取的是-2
	PopupWindow popupWindow = new PopupWindow(contentView, 400, 400,true);
	
	//设置背景图片,如果有这里的代码,点击对话框外面窗体关闭,否则不关闭
	//popupWindow.setBackgroundDrawable(new BitmapDrawable());
	//Note:如果你是用这种方式写的代码,点击对话框外面窗体不关闭关闭
	//popupWindow.setBackgroundDrawable(null);
	
	//设置PopupWindow的布局
	//popupWindow.setContentView(contentView);
	//如果你不在显示PopupWindow之前设置为true,你操作PopupWindow将无效
	//popupWindow.setFocusable(true);
	
	//设置dismiss监听
	//popupWindow.setOnDismissListener(onDismissListener)		
	
	popupWindow.setTouchable(true);
	//当然这里很明显只能在 Touchable 下才能使 用。 
	popupWindow.setOutsideTouchable(true);
	
	//触摸拦截
	//popupWindow.setTouchInterceptor(l);		
	popupWindow.update();
	return popupWindow;
}

NOTE:popupWindow.setTouchable(false);默认是true,如果这里是false,点击popupWindow外面,popupWindow不消失,按返回键消失;如果这里是true,点击popupWindow外面,popupWindow消失,按返回键消失,这个是有设置了popupWindow.setBackgroundDrawable(new BitmapDrawable());为前提的。popupWindow.setTouchable(false);默认是true,然这里很明显只能在 Touchable下才能使用,这个个人没有觉的有什么用,设置了也没有效果,可以通过上面的方式搭配实现。

若在Activity的onCreate()方法中直接写弹出PopupWindow方法会报错,因为activity没有完全启动是不能弹出PopupWindow的。如果要在Activity加载完的时候弹PopupWindow怎么办。下面给大家介绍三种方法(我就直接贴代码):

第一种方法: 利用Activity的 onWindowFocusChanged()方法

//判断PopupWindow是否显示
private boolean isShow = true;
@Override //窗体焦点改变的时候调用,如果窗体出现关闭不掉就需要这么优化
//PopupWindow关闭的时候,Activity获取焦点,也会调用这个方法,所以窗体会出现关不掉的情况
public void onWindowFocusChanged(boolean hasFocus) {
	super.onWindowFocusChanged(hasFocus);
	if (hasFocus) {
		if (isShow) {
			isShow = false;
			PopupWindow popupWindow = PopupWindowTest.initPopWindow(context,R.layout.pop_dialog);			
			popupWindow.showAsDropDown(tv);
		}
	}
}

@Override
protected void onRestart() {
	super.onRestart();
	isShow = true;
}
第二种方法: 利用Handler和Runnable

private Handler mHandler = new Handler();

private Runnable mRunnable = new Runnable() {		
	@Override
	public void run() {
		//弹出PopupWindow的代码
		PopupWindow popupWindow = PopupWindowTest.initPopWindow(context,R.layout.pop_dialog);			
		popupWindow.showAsDropDown(tv);
	}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	mHandler.postDelayed(mRunnable, 500);
}
第三种方法: 直接利用Handler

private Handler mHandler = new Handler(){
	public void handleMessage(android.os.Message msg) {
		switch (msg.what) {
		case 1:
			//弹出PopupWindow的代码
			PopupWindow popupWindow = PopupWindowTest.initPopWindow(context,R.layout.pop_dialog);			
			popupWindow.showAsDropDown(tv);
			break;
		default:
			break;
		}
	};
};

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	Message msg = new Message();
	msg.what = 1;
	mHandler.sendMessageDelayed(msg, 500);
}

AlertDialog比较简单,直接贴代码:

private static AlertDialog alertDialog;
public static void initAlertDialog(Context context,boolean cancelable,boolean canceledOnTouchOutside){
	//在创建对话框的时候可以设置一个style
	alertDialog = new AlertDialog.Builder(context,R.style.dialogtest).create();
	//点击返回键是否可以关闭 默认是True
	alertDialog.setCancelable(cancelable);
	//点击窗口外面是否可以关闭 
	alertDialog.setCanceledOnTouchOutside(canceledOnTouchOutside);
	alertDialog.show();
	//NOTE:一定要先show在设置布局
	alertDialog.setContentView(R.layout.pop_dialog);
	alertDialog.dismiss();
}

样式代码

<style name="dialog" parent="@android:style/Theme.Dialog">
    <item name="android:windowFrame">@null</item><!--边框-->
    <item name="android:windowIsFloating">true</item><!--是否浮现在activity之上-->
    <item name="android:windowIsTranslucent">false</item><!--半透明-->
    <item name="android:windowNoTitle">true</item><!--无标题-->
    <item name="android:windowBackground">@color/transparent</item><!--背景透明-->
    <item name="android:backgroundDimEnabled">false</item><!--模糊,后面有一个灰黑色的充满整个屏幕-->
</style>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值