AlertDialog和PopupWindow
介绍
AlertDialog是一个弹框,这个弹框可以屏蔽其他控件的交互能力,所以一般用来提示比较重要的信息,给用户提示或者强制用户处理。
PopupWindow 实际上是一个悬浮框。
区别:
1:AlertDialog的位置是固定的,而PopupWindow的位置可以是随意的。
2:AlertDialog是非线程阻塞的,而PopupWindow是线程阻塞的。
AlertDialog
实现方式
- 通过AlertDialog.Builder 获取Builder对象。
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
- 调用setTitle、setMessage、setIcon等方法赋值。
setTitle(CharSequece title);
setIcon(int iconID);
setMessage(CharSequece title);
setView(View view);
- 设置按钮。
setPositiveButton 确定按钮
setNegativeButton 取消按钮
setNeutralButton 中间按钮
- 调用builder的create方法创建AlertDialog对象。
- 调用show方法,让对话框在界面上显示。
实现代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#FFFFFF"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="加载AlertDialog弹框"
android:onClick="loadDialog"
/>
</LinearLayout>
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.NotificationCompat;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void loadDialog(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("我是AlertDialog")
.setIcon(R.drawable.ic_baseline_contact_phone_24)
.setMessage("AlertDialog消息框区域");
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// TODO
Log.e("AlertDialog","确定");
Toast.makeText(getApplicationContext(), "确定~", Toast.LENGTH_SHORT).show();
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// TODO
Log.e("AlertDialog","取消");
Toast.makeText(getApplicationContext(), "取消~", Toast.LENGTH_SHORT).show();
}
});
builder.setNeutralButton("其他", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// TODO
Log.e("AlertDialog","其他");
Toast.makeText(getApplicationContext(), "其他~", Toast.LENGTH_SHORT).show();
}
});
// 创建
builder.create();
// 显示
builder.show();
}
}
PopupWindow
构造方法
public PopupWindow (Context context)
public PopupWindow(View contentView, int width, int height)
public PopupWindow(View contentView)
// focusable是否显示焦点,设置为true,点击
public PopupWindow(View contentView, int width, int height, boolean focusable)
方法
setContentView(View contentView) | 设置PopupWindow显示的View |
getContentView() | 获得PopupWindow显示的View |
showAsDropDown(View anchor) | 相对某个控件的位置(正左下方),无偏移 |
showAsDropDown(View anchor, int xoff, int yoff) | 相对某个控件的位置,有偏移 |
showAtLocation(View parent, int gravity, int x, int y) | 相对于父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以设置偏移或无偏移 PS:parent这个参数只要是activity中的view就可以了! |
setWidth/setHeight | 设置宽高,也可以在构造方法那里指定好宽高, 除了可以写具体的值,还可以用WRAP_CONTENT或MATCH_PARENT, popupWindow的width和height属性直接和第一层View相对应。 |
setFocusable(true) | 设置焦点,PopupWindow弹出后,所有的触屏和物理按键都由PopupWindows 处理。其他任何事件的响应都必须发生在PopupWindow消失之后,(home 等系统层面的事件除外)。 比如这样一个PopupWindow出现的时候,按back键首先是让PopupWindow消失,第二次按才是退出 activity,准确的说是想退出activity你得首先让PopupWindow消失,因为不并是任何情况下按back PopupWindow都会消失,必须在PopupWindow设置了背景的情况下 。 |
setAnimationStyle(int) | 设置动画效果 |
代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#706B6B"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="加载PopupWindow弹框"
android:onClick="loadDialog"
/>
</LinearLayout>
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.PopupWindow;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void loadDialog(View view) {
View inflate = getLayoutInflater().inflate(R.layout.popup_layout, null);
// ViewGroup.LayoutParams.WRAP_CONTENT 指的是刚刚包裹控件的含义
PopupWindow popupWindow = new PopupWindow(inflate, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
// 设置加载动画
// popupWindow.setAnimationStyle(R.drawable.cartoon);
/**
* 这些为了点击非PopupWindow区域,PopupWindow会消失的,
* 如果没有下面的代码的话,你会发现,当你把PopupWindow显示出来了,无论你按多少次后退键
* PopupWindow并不会关闭,而且退不出程序,加上下述代码可以解决这个问题
*/
popupWindow.setTouchable(true);
popupWindow.setTouchInterceptor(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return false;
// 这里如果返回true的话,touch事件将被拦截
// 拦截后 PopupWindow的onTouchEvent不被调用,这样点击外部区域无法dismiss
}
});
popupWindow.setBackgroundDrawable(new ColorDrawable(0x00000000)); //要为popWindow设置一个背景才有效
// 这边的参数View,指的是显示在某个View的下方, x轴偏移量, y轴偏移量
popupWindow.showAsDropDown(view,100,100);
}
}
关于PopupWindow,可以参考:PopupWindow(悬浮框)的基本使用