可以参考另一个博主的文章
Android 必知必会 – DialogFragment 使用总结
**
背景
Android 官方推荐使用 DialogFragment 来代替 Dialog ,可以让它具有更高的可复用性(降低耦合)和更好的便利性(很好的处理屏幕翻转的情况)。
而创建 DialogFragment 有两种方式:
覆写其 onCreateDialog 方法 — ①
覆写其 onCreateView 方法 — ②
虽然这两种方式都能实现相同的效果,但是它们各有自己适合的应用场景:
方法 ①,一般用于创建替代传统的 Dialog 对话框的场景,UI 简单,功能单一。
方法 ②,一般用于创建复杂内容弹窗或全屏展示效果的场景,UI 复杂,功能复杂,一般有网络请求等异步操作。
DialogFragment不像Dialog使用的时候,例如横竖屏的切换(Activity的生命周期会改变),就造成了dialog会消失 ,DialogFragment则不会,只有Activity消失他才会消失。
使用DialogFragment的时候可以使用onCreateView自定义布局,也可以在onCreateDialog方法中使用以前传统的方式书写。
在onCreateDialog中实现
public class UpdateMoneyDialog extends DialogFragment {
private Activity activity;
private Context context;
private LayoutInflater inflater;
private Dialog dialog;
private View view;
private TextView tvCancel;
private TextView tvConfirm;
private EditText etMoney;
private int position;
private TextView tvName;
@Override
public void onAttach(Context context) {
super.onAttach(context);
this.context = context;
this.activity = (Activity) context;
}
public static UpdateMoneyDialog getInstance(String money,int postion,String name){
UpdateMoneyDialog imgShowDialog = new UpdateMoneyDialog();
Bundle bundle = new Bundle();
bundle.putString("money",money);
bundle.putInt("pos",postion);
bundle.putString("name",name);
//传入值,跟Fragment传值方法一样
imgShowDialog.setArguments(bundle);
return imgShowDialog;
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
inflater = LayoutInflater.from(context);
dialog = new Dialog(context, R.style.bran_online_supervise_dialog);
view = inflater.inflate(R.layout.update_money_dialog_layout, null);
tvCancel = (TextView) view.findViewById(R.id.tv_cancel);
tvConfirm = (TextView) view.findViewById(R.id.tv_confirm);
tvName = (TextView) view.findViewById(R.id.tv_name);
etMoney = (EditText) view.findViewById(R.id.et_money);
//设置取消标题
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
//设置点击外部不可以消失
dialog.setCanceledOnTouchOutside(true);
//设置即使点击返回键也不会退出
setCancelable(true);
dialog.setContentView(view);
//将值取出来
Bundle bundle = getArguments();
if(null != bundle){
position = bundle.getInt("pos");
String money = bundle.getString("money");
etMoney.setText(money);
String name = bundle.getString("name");
tvName.setText(name);
}
tvCancel.setOnClickListener(onClickListener);
tvConfirm.setOnClickListener(onClickListener);
//获取当前Activity所在的窗体
Window dialogWindow = dialog.getWindow();
//设置软键盘弹出模式
dialogWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
//获得窗体的属性
WindowManager.LayoutParams lp = dialogWindow.getAttributes();
lp.gravity = Gravity.BOTTOM;
//设置Dialog宽度匹配屏幕宽度
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
//设置Dialog高度自适应
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
//将属性设置给窗体
dialogWindow.setAttributes(lp);
return dialog;
}
/**
* View的点击事件
*/
View.OnClickListener onClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.tv_cancel:
KeyboardUtils.hideSoftInput(activity,tvCancel);
dialog.dismiss();
break;
case R.id.tv_confirm:
String money = etMoney.getText().toString().trim();
if(!TextUtils.isEmpty(money)){
listener.onObtainValue(position,money);
KeyboardUtils.hideSoftInput(activity,tvConfirm);
dialog.dismiss();
}else{
listener.onObtainValue(position,"0");
KeyboardUtils.hideSoftInput(activity,tvConfirm);
dialog.dismiss();
}
break;
default:
break;
}
}
};
public interface OnUpdateMoneyListener{
void onObtainValue(int position,String data);
}
private OnUpdateMoneyListener listener = null;
public void setOnUpdateMoneyListener(OnUpdateMoneyListener listener){
this.listener = listener;
}
@Override
public void onDestroy() {
super.onDestroy();
KeyboardUtils.hideSoftInput(activity);
if(dialog != null){
dialog.dismiss();
dialog = null;
}
}
}
DialogFragment的一下窗口属性
<style name="bran_online_supervise_dialog" parent="@android:style/Theme.Dialog">
<!-- 背景透明 -->
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
<!--透明度40%-->
<item name="android:backgroundDimAmount">0.4</item>
<!-- 浮于Activity之上 -->
<item name="android:windowIsFloating">true</item>
<!-- 边框 -->
<item name="android:windowFrame">@null</item>
<!-- Dialog以外的区域模糊效果 -->
<item name="android:backgroundDimEnabled">true</item>
<!-- 无标题 -->
<item name="android:windowNoTitle">true</item>
<!-- 半透明 -->
<!--<item name="android:windowIsTranslucent">true</item>-->
<!-- Dialog进入及退出动画 -->
<item name="android:windowAnimationStyle">@style/bran_online_supervise_animation</item>
</style>
<!-- Dialog从底部进出动画 -->
<style name="bran_online_supervise_animation" parent="@android:style/Animation.Dialog">
<item name="android:windowEnterAnimation">@anim/dialog_enter_anim</item>
<item name="android:windowExitAnimation">@anim/dialog_exit_anim</item>
</style>
进入动画dialog_enter_anim
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false"
>
<translate
android:fromYDelta="100%p"
android:toYDelta="0"
android:duration="500"
/>
<alpha
android:fromAlpha="0"
android:toAlpha="1.0"
android:duration="500"
/>
</set>
退出动画dialog_exit_anim
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false"
>
<translate
android:fromYDelta="0"
android:toYDelta="100%p"
android:duration="500"
/>
<alpha
android:fromAlpha="1.0"
android:toAlpha="0"
android:duration="500"
/>
</set>
在onCreateView中实现自定义
public class CustomDiaFrag extends DialogFragment {
@BindView(R.id.tv_title)
TextView tvTitle;
@BindView(R.id.tv_content)
TextView tvContent;
@BindView(R.id.tv_comfirm)
TextView tvComfirm;
@BindView(R.id.tv_cancel)
TextView tvCancel;
Unbinder unbinder;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_TITLE,R.style.AppTheme);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.custom_dia_frag_layout, container, false);
unbinder = ButterKnife.bind(this, view);
Window window = getDialog().getWindow();
window.setBackgroundDrawable(new ColorDrawable(0x80000000));
WindowManager.LayoutParams params = window.getAttributes();
params.gravity = Gravity.CENTER;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
window.setAttributes(params);
tvComfirm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
tvCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
return view;
}
public static CustomDiaFrag newInstance() {
return new CustomDiaFrag();
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
}
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.constraint.ConstraintLayout
android:layout_width="300dp"
android:layout_height="200dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:background="#55000000"
>
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="标题"
android:textColor="#0da38c"
android:textSize="18sp"
android:layout_marginTop="20dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>
<TextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="你原来是内容"
android:textSize="15sp"
android:textColor="#192c9c"
app:layout_constraintTop_toBottomOf="@id/tv_title"
android:layout_marginTop="20dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>
<TextView
android:id="@+id/tv_comfirm"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="确定"
android:textSize="18sp"
android:textColor="#FF8B3D"
app:layout_constraintBottom_toBottomOf="parent"
android:padding="5dp"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/tv_cancel"
android:gravity="center"
android:layout_marginBottom="20dp"
/>
<TextView
android:id="@+id/tv_cancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="取消"
android:textSize="18sp"
android:textColor="#FF8B3D"
app:layout_constraintBottom_toBottomOf="parent"
android:padding="5dp"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toRightOf="@id/tv_comfirm"
android:gravity="center"
android:layout_marginBottom="20dp"
/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
下面补充一下DialogFragment的第二种用法(onCreateView),使用方式跟我们的Fragment相同,跟Fragment一样一般使用V4包的类
public class CustomDialog extends DialogFragment {
@BindView(R.id.tv_title)
TextView tvTitle;
@BindView(R.id.tv_content)
TextView tvContent;
@BindView(R.id.bt_cancel)
Button btCancel;
@BindView(R.id.bt_confirm)
Button btConfirm;
Unbinder unbinder;
private Activity activity;
@Override
public void onAttach(Context context) {
super.onAttach(context);
activity = (Activity) context;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_TITLE, R.style.custom_dialog);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.custom_dialog_layout, null);
unbinder = ButterKnife.bind(this, view);
init();
return view;
}
private void init() {
Dialog dialog = getDialog();
dialog.setCanceledOnTouchOutside(true);
dialog.setCancelable(true);
Window window = dialog.getWindow();
//设置dialog的背景颜色,我们可以直接在XML中给dialog加一个背景色,如果不设置背景颜色就会造成背景是透明的
//window.setBackgroundDrawable(new ColorDrawable(0x00000000));
window.getDecorView().setPadding(0, 0, 0, 0);
//获得窗体的属性
WindowManager.LayoutParams lp = window.getAttributes();
lp.gravity = Gravity.CENTER;
//设置Dialog宽度匹配屏幕宽度
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
//设置Dialog高度自适应
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
//将属性设置给窗体
window.setAttributes(lp);
}
@OnClick(R.id.bt_cancel)
public void toCancel(){
dismiss();
}
@OnClick(R.id.bt_confirm)
public void toConfirm(){
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
}
^_^,还有个小东西,不知道你们发现没有,经常使用UC浏览器就会发现它经常弹出让我们给评价的dialog,动画效果是从顶部下来的,改成下面的动画进入方式就可以了
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false"
>
<translate
android:fromYDelta="-100%p"
android:toYDelta="0"
android:duration="500"
/>
<!--
<translate
android:fromYDelta="100%p"
android:toYDelta="0"
android:duration="500"
/>
-->
<alpha
android:fromAlpha="0"
android:toAlpha="1.0"
android:duration="500"
/>
</set>