因为Fragment能够根据Activity的情况自动改变生命周期,而通过使用DialogFragment制作对话框,关于生命周期的管理比较容易,也不会出bug,所以Google后来推荐使用DialogFragment而不是AlertDialog。
关于DialogFragment的使用我们只需使用show函数就可以显示它,而且他也可以设置点击其他区域取消对话框,使用方法和AlertDialog相似。
下面我说说QQ控件的评论对话框的实现,这个例子不是我写,是博文最后的参考文章的博主写的
1.首先点击想要评论的字样,弹出对话框
关于这个步,你可以当做你点击一个按钮弹出DialogFragment
CommentDialogFragment commentDialogFragment = new CommentDialogFragment();
commentDialogFragment.show(getFragmentManager(), "CommentDialogFragment");
2.实现输入框显示在下面
首先DialogFragment想要实现对话框的效果,他自己要去实现onCreateDialog函数,返回一个View,这个View用不着覆盖整个屏幕,只需按自己需求设计大小,背后会显示灰色并透明,和一般的AlertDiaog背景一样
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog mDialog = new Dialog(getActivity(), R.style.BottomDialog);
mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
mDialog.setContentView(R.layout.dialog_fragment_comment_layout);
mDialog.setCanceledOnTouchOutside(true);
return mDialog;
}
但是这还没有实现对话框在下方的效果,他这一步很精髓,通过设置Dialog的window的LayoutParams属性来设置Dialog的大小和位置
Window window = mDialog.getWindow();
WindowManager.LayoutParams layoutParams;
if (window != null) {
layoutParams = window.getAttributes();
layoutParams.gravity = Gravity.BOTTOM;
layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
window.setAttributes(layoutParams);
}
3.弹出评论框的同时,弹出软键盘
private void setSoftKeyboard() {
commentEditText.setFocusable(true);
commentEditText.setFocusableInTouchMode(true);
commentEditText.requestFocus();
//为 commentEditText 设置监听器,在 DialogFragment 绘制完后立即呼出软键盘,呼出成功后即注销
commentEditText.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
inputMethodManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
if (inputMethodManager != null) {
if (inputMethodManager.showSoftInput(commentEditText, 0)) {
commentEditText.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
}
}
});
}
4.对话框取消和结束带回输入字符
想要将Fragment的数据传递给Activity,需要Activity里实现实现接口,Fragment调用接口
接口定义
public interface DialogFragmentDataCallback {
String getCommentText();
void setCommentText(String commentTextTemp);
}
Activity实现接口
@Override
public String getCommentText() {
return commentFakeButton.getText().toString();
}
@Override
public void setCommentText(String commentTextTemp) {
commentFakeButton.setText(commentTextTemp);
}
然后是Fragment获取调用接口
dataCallback = (DialogFragmentDataCallback) getActivity();
然后通过重写onDismiss和onCancel来获取数据,并通过接口回调给Activity
@Override
public void onDismiss(DialogInterface dialog) {
dataCallback.setCommentText(commentEditText.getText().toString());
super.onDismiss(dialog);
}
@Override
public void onCancel(DialogInterface dialog) {
dataCallback.setCommentText(commentEditText.getText().toString());
super.onCancel(dialog);
}
完整代码:https://github.com/showzeng/PureComment
参考博客:
https://showzeng.itscoder.com/android/2017/08/11/the-imitation-of-the-international-weibo-comment-box.html