分别用PopupWindow和AlertDialog实现对话框实例

实现效果是:点击主界面的按钮,调用showDialog方法,显示的是一个登陆对话框,对话框布局在R.layout.login中。

首先是使用PopupWindow:

public class MainActivity extends Activity {
	private AlertDialog mDialog;
	private EditText editText, passwordText;
	private InputMethodManager imm = null;
	private View wholeView, view;
	private PopupWindow window;
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		getWindow().requestFeature(Window.FEATURE_NO_TITLE);
		LayoutInflater inflater = LayoutInflater.from(this);
		wholeView = inflater.inflate(R.layout.activity_main, null);
		setContentView(wholeView);
		
	}
	public void showDialog(View v){
		
		WindowManager.LayoutParams lp = getWindow().getAttributes();
		lp.alpha = 0.8f;
		getWindow().setAttributes(lp);
				
		LayoutInflater lay = getLayoutInflater();
		view = lay.inflate(R.layout.login, null);
		//获得view的方式
		Button login = (Button)view.findViewById(R.id.login);
		login.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				window.dismiss();
			}
		});
		
		window = new PopupWindow(view, 400, 300, true);
		//window.setFocusable(true);
		window.setBackgroundDrawable(new BitmapDrawable());
		window.showAtLocation(wholeView, Gravity.CENTER, 0, 0);
		window.setOnDismissListener(new OnDismissListener(){
			public void onDismiss() {
				WindowManager.LayoutParams lp = getWindow().getAttributes();
				lp.alpha = 1;
				getWindow().setAttributes(lp);				
			}			
		});
		
	}
}


实现要点:

        popupWindow.setFocusable(true);这一点很重要。这样才能让popupWindow里面的布局控件获得点击的事件,否则就被它的父亲view给拦截了。

如果给 PopupWindow setFocusable(true),此时屏幕的焦点在PopupWindow上面,parent无法响应的按键事件,只会 PopupWindow

响应的按键事件。public PopupWindow (View contentView, int width, int height, boolean focusable),第四个参数我们设置为true就可以了。

        PopupWindow在Focusable为false的情况下,我们使用遥控无法选中输入框,虽然鼠标点击按钮能有响应,但用鼠标点击输入

框无法出现输入法,而此时主界面可以接收按键事件。

        总而言之:PopupWindow与Dialog不同之处在于PopupWindow弹出时背景Activity仍可以获取焦点(PopupWindow setFocusable(

false) 除外),设置SetFocusable(true)后,与Dialog相似,并且不能接收按键事件。

        如果要使PopupWindow能响应按键事件或点击背景Activity以关闭弹出对话框 最简单的方法是使用setBackgroundDrawable()

,或者使用能创建Background的构造方法 这是因为当设置了background后会将contentView放在一个PopupViewContainer类的容器

交给WindowManager,PopupViewContainer是PopupView的内部类,实现了对按键及Touch事件的处理。当然不设background自

己通过set对最外层contentView调用setOnKeyListener(),setOnTouchListener()也可实现。

这里当键盘出来时,原布局并没有压缩。


使用AlertDialog

public void showDialog(View v){ 
        mDialog = new AlertDialog.Builder(this).create();  
        mDialog.show();  
        Window window = mDialog.getWindow();
        window.setContentView(R.layout.login);  
          
        //获得view的方式  
        editText = (EditText)window.findViewById(R.id.username);  
          
        //AlertDialog弹出时,背景是黑色的,在此我们更改黑色幕布透明度为彻底透明
        window.clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);  
        WindowManager.LayoutParams lp = window.getAttributes();
		lp.dimAmount = 0.0f;
		mDialog.onWindowAttributesChanged(lp);
		
        mDialog.setOnKeyListener(mDialog_onKeyListener);  
        mDialog.setCanceledOnTouchOutside(false);  
    }  
    private DialogInterface.OnKeyListener mDialog_onKeyListener = new DialogInterface.OnKeyListener() {  
        public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {  
            if (event.getAction() == KeyEvent.ACTION_DOWN) {  
                if (keyCode == KeyEvent.KEYCODE_BACK) {//按返回键对话框消失,透明度恢复  
                    mDialog.dismiss();  
                    WindowManager.LayoutParams lp = getWindow().getAttributes();  
                    lp.alpha = 1;  
                    getWindow().setAttributes(lp);  
                }  
            }  
            return false;  
        }  
    };  

在AlertDialog中需手动显示输入法,故需加语句

alertDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);

WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM是指定alertDialog出现在最前,Often you will want to have a Dialog display on top of the current input method, because there is no reason for it to accept text.除了上面语句

window.setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);可实现同样效果。

弹出输入法时会 把后面的背景压缩


PopupWindow和AlertDialog区别

Android的对话框有两种:PopupWindowAlertDialog

 

它们的不同点在于:AlertDialog的位置固定,而PopupWindow的位置可以随意
AlertDialog是非阻塞线程的,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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PopupWindow是Android系统提供的一种弹出式窗口,可以在当前界面上方弹出一个新的视图。它通常用于下拉菜单、浮动菜单、提示框等场景。 创建PopupWindow需要以下步骤: 1. 创建PopupWindow对象; 2. 设置PopupWindow的宽度、高度、背景等属性; 3. 设置PopupWindow的ContentView,即弹出窗口所包含的视图; 4. 设置PopupWindow的位置; 5. 显示PopupWindow。 使用PopupWindow需要注意以下几点: 1. PopupWindow必须有一个父视图,即它必须依附于某个Activity或者View上; 2. 在设置PopupWindow的位置时,要根据父视图的位置进行计算,确保弹出窗口显示在合适的位置; 3. 如果需要点击弹出窗口以外的区域关闭弹出窗口,可以设置PopupWindow的setOutsideTouchable方法为true,并设置一个背景Drawable。 下面是一个简单的示例代码: ``` // 创建PopupWindow对象 PopupWindow popupWindow = new PopupWindow(context); // 设置PopupWindow的宽度、高度、背景等属性 popupWindow.setWidth(WindowManager.LayoutParams.WRAP_CONTENT); popupWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT); popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); // 设置PopupWindow的ContentView View contentView = LayoutInflater.from(context).inflate(R.layout.popup_window_layout, null); popupWindow.setContentView(contentView); // 设置PopupWindow的位置 int[] location = new int; parentView.getLocationOnScreen(location); popupWindow.showAtLocation(parentView, Gravity.NO_GRAVITY, location, location + parentView.getHeight()); // 显示PopupWindow popupWindow.showAsDropDown(anchorView); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值