原因
官方推荐的方式是使用AlertDialog,DialogFragment来实现。虽然说很多网上的例子直接使用了extends
Dialog来实现,但大部分时间我们应该使用上述的两种方式,因为有时候没有考虑到旋转或者Activity到后台后,Dialog附在的Activity消失,引起内存泄露的问题。
国内很多应用喜欢用Dialog的方式,基本上很大程度上要自定义Dialog中的button,这时候用DialogFragment其实可以实现,而且实现上也比较方便。
如同官方Dialog 类是对话框的基类,但您应该避免直接实例化
Dialog,而是使用下列子类之一:
说的这样,我们应该使用extends类。
实现方式
其实主要讲解是DialogFragment,主要是国内的应用还是在仿IOS,少有遵循Material
Design的设计,所以Button也是需要自定义的,那么AlertDialog就无法满足需要。这里引用官方的一段描述。
这些类定义您的对话框的样式和结构,但您应该将 DialogFragment
用作对话框的容器。DialogFragment 类提供您创建对话框和管理其外观所需的所有控件,而不是调用 Dialog 对象上的方法。
使用 DialogFragment
管理对话框可确保它能正确处理生命周期事件,如用户按“返回”按钮或旋转屏幕时。 此外,DialogFragment 类还允许您将对话框的 UI
作为嵌入式组件在较大 UI 中重复使用,就像传统 Fragment 一样(例如,当您想让对话框 UI
在大屏幕和小屏幕上具有不同外观时)。
重写onCreateView()
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View inflate = inflater.inflate(R.layout.fragment_edit_name, container, false);
mEditText = (EditText) inflate.findViewById(R.id.txt_your_name);
mButton1 = (Button) inflate.findViewById(R.id.btn1);
mButton2 = (Button) inflate.findViewById(R.id.btn2);
return inflate;
}
这样基本就完成了,什么样式都在于你自己去实现。
设置有输入的Dialog调整,当键盘弹出
希望键盘可以说弹出,并且不挡住取消和确定这类的Button时,可以在onactivityCreated()
中设置,其它地方也可以说。
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
}
其中SOFT_INPUT_STATE_*中的各类型见名知意,这样了弹出直接拉起键盘,对用户也十分方便。更具体的使用请参考官方的DialogFragment。
如下图所示为弹出和键盘自动弹出的情况,然后收缩键盘的情况。
如果说显示的内容特别多还是会把下面的给遮挡住的。下面这张图的情况就是过长的内容并不会把内容往上移动,因为移动已经超出屏幕了。
关于宽度设置为match_parent
时不占全的解决办法
在一些情况下有这种要求,处理很容易在onStart()
中把背景色处理一下就可以了,也有说传null,但我认为下面方式更好些。
@Override
public void onStart() {
super.onStart();
getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
}
使用AlertDialog方式实现
这个时候不需要实现onCreateView()
,这时应该实现public Dialog onCreateDialog(Bundle
savedInstanceState)
,如下代码所示。
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View inflate = inflater.inflate(R.layout.dialog_test, null);
mEditText = (EditText) inflate.findViewById(R.id.editText);
mEditTest2 = (EditText) inflate.findViewById(R.id.editText2);
builder.setView(inflate)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
TestDialog.this.getDialog().cancel();
}
});
return builder.create();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
如果之后需要request focus,应该在onActivityCreated()
里面写。
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mEditText.requestFocus();
getDialog().setTitle("haha");
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
}
关于Dialog位置和背景的设置
需要设置时需要
得到顶层的window,可以参考下面的代码段1,代码段2。
Dialog dlg = <code to create custom dialog>;
Window window = dlg.getWindow();
WindowManager.LayoutParams wlp = window.getAttributes();
wlp.gravity = Gravity.BOTTOM;
wlp.flags &= ~WindowManager.LayoutParams.FLAG_DIM_BEHIND;
window.setAttributes(wlp);
private CharSequence[] items = {"Set as Ringtone", "Set as Alarm"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
if(item == 0) {
} else if(item == 1) {
} else if(item == 2) {
}
}
});
AlertDialog dialog = builder.create();
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
WindowManager.LayoutParams wmlp = dialog.getWindow().getAttributes();
wmlp.gravity = Gravity.TOP | Gravity.LEFT;
wmlp.x = 100;
wmlp.y = 100;
dialog.show();
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24