适用于简单的表单场景。
在 res/layout
中新建 dialog_form.xml
:
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="姓名"/>
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="邮箱"
android:inputType="textEmailAddress"/>
在 Activity
或 Fragment
中:
// 点击按钮触发弹窗
findViewById(R.id.btn_show_dialog).setOnClickListener(v -> showFormDialog());
private void showFormDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
LayoutInflater inflater = getLayoutInflater();
View dialogView = inflater.inflate(R.layout.dialog_form, null);
EditText etName = dialogView.findViewById(R.id.etName);
EditText etEmail = dialogView.findViewById(R.id.etEmail);
builder.setView(dialogView)
.setTitle("编辑信息")
.setPositiveButton("确认", (dialog, which) -> {
String name = etName.getText().toString();
String email = etEmail.getText().toString();
// 处理输入数据
Toast.makeText(this, "提交: " + name + ", " + email, Toast.LENGTH_SHORT).show();
})
.setNegativeButton("取消", (dialog, which) -> dialog.dismiss());
AlertDialog dialog = builder.create();
dialog.show();
}
适合需要复用或包含复杂逻辑的表单。
public class FormDialogFragment extends DialogFragment {
public interface FormDialogListener {
void onFormSubmitted(String name, String email);
}
private FormDialogListener listener;
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = requireActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.dialog_form, null);
EditText etName = view.findViewById(R.id.etName);
EditText etEmail = view.findViewById(R.id.etEmail);
builder.setView(view)
.setTitle("编辑信息")
.setPositiveButton("确认", (dialog, which) -> {
String name = etName.getText().toString();
String email = etEmail.getText().toString();
if (listener != null) {
listener.onFormSubmitted(name, email);
}
})
.setNegativeButton("取消", (dialog, which) -> dismiss());
return builder.create();
}
// 设置监听器
public void setFormDialogListener(FormDialogListener listener) {
this.listener = listener;
}
}
// 显示弹窗
FormDialogFragment dialog = new FormDialogFragment();
dialog.setFormDialogListener(new FormDialogFragment.FormDialogListener() {
@Override
public void onFormSubmitted(String name, String email) {
// 处理提交数据
Toast.makeText(MainActivity.this, "提交: " + name + ", " + email, Toast.LENGTH_SHORT).show();
}
});
dialog.show(getSupportFragmentManager(), "FormDialog");
在 styles.xml
中定义对话框样式:
在代码中使用自定义主题:
AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.CustomDialog);
在 Android 中实现弹窗固定在特定位置(如屏幕顶部、底部或自定义坐标),可以通过以下两种方式实现
AlertDialog
控制位置使用 Window
属性设置弹窗的位置和样式。
// 点击按钮触发弹窗
findViewById(R.id.btn_show_dialog).setOnClickListener(v -> {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
LayoutInflater inflater = getLayoutInflater();
View dialogView = inflater.inflate(R.layout.dialog_custom, null);
builder.setView(dialogView)
.setTitle("固定位置的弹窗")
.setPositiveButton("确定", null)
.setNegativeButton("取消", null);
AlertDialog dialog = builder.create();
dialog.show();
// 关键代码:获取 Window 并设置位置
Window window = dialog.getWindow();
if (window != null) {
WindowManager.LayoutParams params = window.getAttributes();
// 设置弹窗位置(例如:顶部居中)
params.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
// 可选:设置偏移量(单位:像素)
params.y = 100; // 距离顶部的偏移
window.setAttributes(params);
}
});
DialogFragment
控制位置更适合复杂场景或需要复用的弹窗。
DialogFragment
public class FixedPositionDialogFragment extends DialogFragment {
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = requireActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.dialog_custom, null);
builder.setView(view)
.setTitle("固定位置的弹窗")
.setPositiveButton("确定", null)
.setNegativeButton("取消", null);
return builder.create();
}
@Override
public void onStart() {
super.onStart();
// 关键代码:设置弹窗位置
Window window = getDialog().getWindow();
if (window != null) {
WindowManager.LayoutParams params = window.getAttributes();
params.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; // 底部居中
params.y = 100; // 距离底部的偏移
window.setAttributes(params);
}
}
}
FixedPositionDialogFragment dialog = new FixedPositionDialogFragment();
dialog.show(getSupportFragmentManager(), "FixedPositionDialog");
参数/方法 | 说明 |
---|---|
gravity |
弹窗的锚点位置,例如 Gravity.TOP 、Gravity.BOTTOM 、Gravity.CENTER |
params.x 和 params.y |
相对锚点的偏移量(单位:像素) |
width 和 height |
弹窗的宽高(例如 MATCH_PARENT 或固定像素值) |
如果需要精确控制弹窗在屏幕上的坐标(例如 (x=200, y=500)
):
Window window = dialog.getWindow();
if (window != null) {
WindowManager.LayoutParams params = window.getAttributes();
params.gravity = Gravity.TOP | Gravity.LEFT; // 左上角为基准
params.x = 200; // 横向偏移
params.y = 500; // 纵向偏移
window.setAttributes(params);
}
屏幕适配:硬编码的像素值(如 params.x = 200
)可能在不同设备上表现不一致,建议使用 dp
转换:
int offsetDp = 50; // 50dp
int offsetPx = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, offsetDp, getResources().getDisplayMetrics()
);
params.y = offsetPx;
动态调整:可通过 window.setLayout(width, height)
控制弹窗大小。
生命周期:在 DialogFragment
中,窗口属性需在 onStart()
或 onResume()
中设置