android弹窗一共有两种方式,一种是dialog及其子类,另一种是popupwindow;Dialog及其子类尤其AlertDialog是最常用的,也是最自由的一种。

**Popupwindow与Dialog的区别:**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等),可以设置偏移或无偏移。其实Popupwindow是自己提供了偏移的设置,但使用AlertDialog获取window对其进行相关设置也能达到弹窗位置随意显示的效果,接下来的高仿QQ空间弹窗就是使用AlertDialog实现任意位置显示弹窗效果的。

——————————————–分割线————————————————–

接下来就要讲高仿QQ空间弹窗的实现
PS:有人喜欢继承Dialog自定义Dialog,但我还是喜欢子在用的到的地方自己写,除非这个dialog会被用多次.
现在讲一下高仿QQ空间弹窗的需求,QQ空间每天说说的右上角会有一个小三角,点击会弹出一个弹窗,同时弹窗会随着Listview中item的小三角的位置变化。不清楚的话用手Q体验一下就好了。

核心代码:

@SuppressLint("NewApi")
public void showDialog(View v) {
    int[] coo = new int[2];// 获取小三角view位置,用来设置dialog的显示位置
    v.getLocationInWindow(coo);
    /* 先实例化dialog并进行相关设置 */
    final AlertDialog dialog = new AlertDialog.Builder(MainActivity.this)
            .create();
    dialog.show();
    dialog.setCanceledOnTouchOutside(true);
    LinearLayout ll = (LinearLayout) getLayoutInflater().inflate(
            R.layout.dialog_content, null);

    dialog.setContentView(ll);
    /*//计算dialog显示的view的高度
    ll.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 
            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
    int ch = ll.getMeasuredHeight();*/
    /* 获取window并进行相关设置 */
    Window window = dialog.getWindow();
    if (coo[1] > sh * 0.65) {//sh指屏幕高度,sw指屏幕宽度,但小三角的位置超过屏幕的65%时,弹窗就变为在小三角上面显示
        window.setWindowAnimations(R.style.mydialog2); // 添加动画
        coo[1] -= sh*0.2;//y轴减去sh*0.2是因为dialog的高度为sh*0.2
    } else {
        window.setWindowAnimations(R.style.mydialog); // 添加动画
    }
    window.setGravity(Gravity.TOP);/*一定要设置为TOP,因为lp中的设置的x,y都是基于这个位置的
    ,如果为TOP,lp设置的y为0时,就在最上面显示,如果为CENTER,y为0时,dialog就在中间显示*/
    /* window的宽高,为window的一部分 */
    WindowManager.LayoutParams lp = window.getAttributes();
    lp.width = (int) (sw * 0.8);
    lp.height = (int) (sh * 0.2);
    lp.y = coo[1];
    window.setAttributes(lp);

}

上面是核心代码,全部代码下载链接:

效果图:

Android 弹窗提醒确认 安卓弹窗控件_分割线


PS:没有美工,界面丑了点