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

来源:互联网 发布:壁虎数据恢复免root版 编辑:程序博客网 时间:2024/06/06 05:35

实现效果是:点击主界面的按钮,调用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 0
原创粉丝点击