1、 概述
DialogFragment在android 3.0时被引入。是一种特殊的Fragment,用于在Activity的内容之上展示一个模态的对话框。典型的用于:展示警告框,输入框,确认框等等。在DialogFragment产生之前,我们创建对话框:一般采用AlertDialog和Dialog。注:官方不推荐直接使用Dialog创建对话框。
2、 好处与用法
使用DialogFragment来管理对话框,当旋转屏幕和按下后退键时可以更好的管理其声明周期,它和Fragment有着基本一致的声明周期。且DialogFragment也允许开发者把Dialog作为内嵌的组件进行重用,类似Fragment(可以在大屏幕和小屏幕显示出不同的效果)。上面会通过例子展示这些好处~使用DialogFragment至少需要实现onCreateView或者onCreateDIalog方法。onCreateView即使用定义的xml布局文件展示Dialog。onCreateDialog即利用AlertDialog或者Dialog创建出Dialog。
3.应用
第一步:首先自定义一个BaseDialog 继承自 DialogFragment
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentManager;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.RelativeLayout;
import java.util.List;
import butterknife.ButterKnife;
import cool.monkey.android.R;
public abstract class BaseDialog extends DialogFragment {
protected boolean mDisableBackPress;
private boolean mEnableTouchCancel;
private boolean mIsShowing;
private boolean mIsAdded;
private List<Integer> mImgList;
protected Handler mHandler;
protected abstract int getLayoutResId();
//控制手机默认Back物理返回键是否Work
public void disableBackPress(boolean disableBackPress) {
this.mDisableBackPress = disableBackPress;
}
public void setEnableTouchCancel(boolean mEnableTouchCancel) {
this.mEnableTouchCancel = mEnableTouchCancel;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(getLayoutResId(), container, false);
ButterKnife.bind(this, view);
mIsAdded = true;
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
View rootView = getView();
if (rootView != null) {
rootView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (mEnableTouchCancel) {
dismiss();
return true;
} else {
return false;
}
}
});
}
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// the content
final RelativeLayout root = new RelativeLayout(getActivity());
root.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
// creating the fullscreen dialog
final Dialog dialog = new Dialog(getActivity());
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
dialog.setContentView(root);
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
dialog.getWindow().getAttributes().windowAnimations = R.style.DialogScaleAnimation;
// listener for back press
dialog.setOnKeyListener(new Dialog.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if (mDisableBackPress && keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
// disable back presse
onBackPressed();
return true;
} else {
return false;
}
}
});
return dialog;
}
protected void onBackPressed() {}
public void tryRecover(FragmentManager fm) {
if (mIsShowing) {
tryShow(fm);
} else {
tryHide();
}
}
public void tryShow(FragmentManager fm) {
if (!hasSavedInstanceState() && !mIsAdded) {
try {
show(fm, getPrivateTag());
mIsAdded = true;
} catch (Exception e) {
e.printStackTrace();
}
}
mIsShowing = true;
}
public void tryHide() {
if (!hasSavedInstanceState() && mIsAdded) {
mIsAdded = false;
super.dismiss();
}
mIsShowing = false;
}
@Override
public void onDismiss(DialogInterface dialog) {
mIsAdded = false;
mIsShowing = false;
super.onDismiss(dialog);
}
@Override
public void dismiss() {
tryHide();
}
protected boolean hasSavedInstanceState() {
return false;
}
private String getPrivateTag() {
return getClass().toString();
}
@Override
public void onDestroyView() {
mIsAdded = false;
super.onDestroyView();
}
public Handler getHandler() {
if (mHandler == null) {
synchronized (this) {
if (mHandler == null) {
mHandler = new Handler(Looper.getMainLooper());
}
}
}
return mHandler;
}
public void doInUI(Runnable runnable) {
doInUI(runnable, 0);
}
public void doInUI(Runnable runnable, long delayMillis) {
getHandler().postDelayed(runnable, delayMillis);
}
}
2.创建具体功能的Dialog
由于DialogFragment 本身就是继承自Fragment 所以用法和Fragment 一样
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;
import cool.monkey.android.R;
import cool.monkey.android.base.BaseDialog;
public class NameInvalidDialog extends BaseDialog {
@BindView(R.id.tv_ok_name_invalid_dialog) TextView mOk;
private NameInvalidDialogListener nameInvalidDialogListener;
Unbinder unbinder;
public void setNameInvalidDialogListener(NameInvalidDialogListener nameInvalidDialogListener) {
this.nameInvalidDialogListener = nameInvalidDialogListener;
}
public interface NameInvalidDialogListener {
void onHide();
}
@Override
protected int getLayoutResId() {
return R.layout.dialog_name_invialid;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = super.onCreateView(inflater, container, savedInstanceState);
unbinder = ButterKnife.bind(this, rootView);
return rootView;
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
@OnClick(R.id.tv_ok_name_invalid_dialog)
public void onOkClicked(View view) {
if (nameInvalidDialogListener != null) {
nameInvalidDialogListener.onHide();
}
tryHide();
}
}
3.在用到的地方展示
public void showDialog() {
NameInvalidDialog nameInvalidDialog = new NameInvalidDialog();
nameInvalidDialog.tryShow(getActivity().getSupportFragmentManager());
}
GitHub: https://github.com/HuaDanJson