- AlertDialog 实现
- 从屏幕底部弹出对话框
- 自定义效果
- Activity 仿 Dialog 效果
部分参考 android 底部弹出提示框的实现方式
基础方法
构造方法
很好几个,要特别说的是这里的第二个,可以加载一个 style ,
是实现 dialog 宽度全屏的关键
Dialog(@NonNull Context context)
Dialog(@NonNull Context context, @StyleRes int themeResId)
设置宽高:
也可以直接使用数值
Window window = dialog.getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
window.setAttributes(params);//设置 dialog 的宽高
设置动画
style 文件,下面会介绍
window.setWindowAnimations(R.style.dialog_anim);//设置动画效果
其他的方法
setTitle(@Nullable CharSequence title) //使用默认的标题
setCustomTitle(@Nullable View customTitleView) //传入一个布局,自定义样式
setIcon(@Nullable Drawable icon) //使用图标做标题
setMessage(@Nullable CharSequence message) // 在标题下按钮上的说明文字
setPositiveButton(CharSequence text, final OnClickListener listener) // 常用于"确定"按钮
setNegativeButton(CharSequence text, final OnClickListener listener) //常用于"取消"按钮
setCancelable(boolean cancelable) // 设置点击框外是否可以关闭,默认为可以
setItems(CharSequence[] items, final OnClickListener listener) //用这个实现简单的列表
setView(View view) //实现自定义的一个布局
监听事件
setOnCancelListener(OnCancelListener onCancelListener)
setOnDismissListener(OnDismissListener onDismissListener)
setOnKeyListener(OnKeyListener onKeyListener)
AlertDialog 基础实现
一个不怎么标准的例子:
因为例子中是在 Fragment 中,通过 LayoutInflater 获取布局。
调用这个 openDialog() 方法即弹出对话框。
private void openDialog() {
LinearLayout linearLayout = (LinearLayout) LayoutInflater.from(getContext()).inflate(R.layout.change_password_dialog, null);
final EditText originPasswordEt = (EditText) linearLayout.findViewById(R.id.origin_password);
TextView forgetPassword = (TextView) linearLayout.findViewById(R.id.forget_password);
final AlertDialog dialog = new AlertDialog.Builder(getContext())
.setTitle("输入密码")
.setView(linearLayout)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String originPassword = originPasswordEt.getText().toString().trim();
//传到后台
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.create();
dialog.show();
forgetPassword.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showToast("忘记密码");
dialog.dismiss();
}
});
}
布局文件:
出现的位置,与相应动画
弹出框出现在屏幕下方
Window window = dialog.getWindow();
window.setGravity(Gravity.BOTTOM); //设置框的位置
弹出框会出现在屏幕下方,但屏幕的左右和下方都有一个小的空隙
要使弹出框布不留有间隙,只改变布局的 layout_width 是不够的,这个是主题 style 导致的
新建一个 style:
并让 dialog 引用这个 style
//在构造函数中引用 style
AlertDialog dialog = new AlertDialog.Builder(getContext(),R.style.Dialog_Full).create();
Window window = dialog.getWindow();
window.setGravity(Gravity.BOTTOM);
//设置横向满屏,纵向自适应,没有这里弹出框会完全布满屏幕
window.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT);
弹出的动画和缩回的动画:
//pop_in.xml
//pop_out.xml
还有一个 style:
设置引用这个 style:
Window window = dialog.getWindow();
window.setGravity(Gravity.BOTTOM);
window.setWindowAnimations(R.style.dialog_anim);//动画效果
window.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT);
dialog.show();//show 必须在 set 后面
效果图就不上了..
自定义效果
将这个控件封装好利于复用,并且可以自定义不同数目的 item 而不需要重写布局。
依然是参考 android 底部弹出提示框的实现方式,添加了一些改动
- 支持放任意多个 Item,但只有文字内容
- 选择是否左右无间隙
- 选择是否有“取消”按钮
- 选择是否可以点击外部关闭
- 文字居中或者靠左
核心代码:
public static Dialog showItemSelectDialog() {
final Dialog dialog;
if (isFull){
dialog = new Dialog(context,R.style.Dialog_Full);//传入布局改变主题
}else {
dialog = new Dialog(context);
}
View rootView = LayoutInflater.from(context).inflate(R.layout.layout_choice,null);
LinearLayout contentsView = (LinearLayout) rootView.findViewById(R.id.dialog_content);
//逐个添加 TextView
for(int i = 0;i < contents.length;i++){
View centerView = LayoutInflater.from(context).inflate(R.layout.dialog_center_item,null);
TextView centerText = (TextView) centerView.findViewById(R.id.dialog_center_item);
final int finali = i;
centerText.setText(contents[finali]);
centerText.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
dialog.dismiss();
if (listener != null){
listener.getSelectedItem(contents[finali]);
}
}
});
if (isTextCenter){
centerText.setGravity(Gravity.CENTER);//水平和垂直居中
}else{
centerText.setPadding(20,0,0,0);
centerText.setGravity(Gravity.CENTER_VERTICAL);//垂直居中
}
contentsView.addView(centerView);
}
Button CancleBtn = (Button) rootView.findViewById(R.id.dialog_cancel);
if (isBtnCancle){
CancleBtn.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
}else {
CancleBtn.setVisibility(View.GONE);
}
dialog.setContentView(rootView);
if (isCancelable){
dialog.setCancelable(true);
dialog.setCanceledOnTouchOutside(true);
}else {
dialog.setCancelable(false);
dialog.setCanceledOnTouchOutside(false);
}
Window window = dialog.getWindow();
WindowManager.LayoutParams params = window.getAttributes();
if (!(isCenter)){
params.gravity = Gravity.BOTTOM;
}
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
window.setAttributes(params);//设置 dialog 的宽高
window.setWindowAnimations(R.style.dialog_anim);//设置动画效果
dialog.show();
return dialog;
}
只是很粗糙的实现,很多可以改进的地方。
但如果再继续折腾下去可能不还如直接用 popupwidow。
用 Activity 实现类似 Dialog 的效果
参考 Android中使用Dialog风格弹出框的Activity
在 style 新建:
然后在 AndroidManifest.xml 中设置 DialogActivity 的 theme