参考:
Android 官方推荐 : DialogFragment 创建对话框
DialogFragment在android 3.0时被引入。是一种特殊的Fragment,用于在Activity的内容之上展示一个模态的对话框。典型的用于:展示警告框,输入框,确认框等等。
在DialogFragment产生之前,我们创建对话框:一般采用AlertDialog和Dialog。注:官方不推荐直接使用Dialog创建对话框。
使用DialogFragment来管理对话框,当旋转屏幕和按下后退键时可以更好的管理其声明周期,它和Fragment有着基本一致的声明周期。且DialogFragment也允许开发者把Dialog作为内嵌的组件进行重用,类似Fragment(可以在大屏幕和小屏幕显示出不同的效果)。上面会通过例子展示这些好处~
使用DialogFragment至少需要实现onCreateView或者onCreateDIalog方法。onCreateView即使用定义的xml布局文件展示Dialog。onCreateDialog即利用AlertDialog或者Dialog创建出Dialog。
a)布局文件,我们创建一个设置dialogFragment的布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/id_label_your_name"
android:layout_width="wrap_content"
android:layout_height="32dp"
android:gravity="center_vertical"
android:text="Your name:" />
<EditText
android:id="@+id/id_txt_your_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/id_label_your_name"
android:imeOptions="actionDone"
android:inputType="text" />
<Button
android:id="@+id/id_sure_edit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@id/id_txt_your_name"
android:text="ok" />
RelativeLayout>
public class EditNameDialogFragment extends DialogFragment
{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_edit_name, container);
return view;
}
}
public void showEditDialog(View view)
{
EditNameDialogFragment editNameDialog = new EditNameDialogFragment();
editNameDialog.show(getFragmentManager(), "EditNameDialog");
}
效果图:
可以看到,对话框成功创建并显示出来,不过默认对话框有个讨厌的标题,我们怎么去掉呢:可以在onCreateView中调用getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);即可去掉。
在DialogFragment的onCreateView方法中添加
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//去除标题栏
Dialog dialog = getDialog();
if (dialog != null) {
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
}
View view = inflater.inflate(R.layout.dialog_layout, container, false);
TextView mTvConfirm = ((TextView) view.findViewById(R.id.dialog_positive));
mTvConfirm.setOnClickListener(this);
return view;
}
在DialogFragment的onStart方法中添加
@Override
public void onStart() {
super.onStart();
//设置动画、位置、宽度等属性(注意一:必须放在onStart方法中)
Window window = getDialog().getWindow();
if (window != null) {
// 注意二:一定要设置Background,如果不设置,window属性设置无效
window.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.white)));
WindowManager.LayoutParams layoutParams = window.getAttributes();
layoutParams.windowAnimations = R.style.MusicDialog;//动画
layoutParams.gravity = Gravity.BOTTOM; // 位置
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;//宽度满屏
window.setAttributes(layoutParams);
}
}
设置宽度撑满屏幕、位置、动画等属性:在onCreateView中设置与onStart中不设置Background一样的效果:全屏未实现。
示例如下:
onStart中不设置Background
public class MyDialogFrag2 extends DialogFragment implements View.OnClickListener {
@Override
public void onStart() {
super.onStart();
//设置动画、位置、宽度等属性(注意一:必须放在onStart和onResume()中设置才有效)
Window window = getDialog().getWindow();
if (window != null) {
// 注意二:一定要设置Background,如果不设置,window属性设置无效
// window.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.white)));
WindowManager.LayoutParams layoutParams = window.getAttributes();
layoutParams.windowAnimations = R.style.MusicDialog;//动画
layoutParams.gravity = Gravity.BOTTOM; // 位置
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;//宽度满屏
window.setAttributes(layoutParams);
}
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Dialog dialog = getDialog();
if (dialog != null) {
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
}
View view = inflater.inflate(R.layout.dialog_layout, container, false);
TextView mTvConfirm = ((TextView) view.findViewById(R.id.dialog_positive));
mTvConfirm.setOnClickListener(this);
return view;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.dialog_positive:
dismiss();
break;
}
}
}
onCreateView中设置:
public class MyDialogFrag3 extends DialogFragment implements View.OnClickListener {
@Override
public void onStart() {
super.onStart();
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//设置动画、位置、宽度等属性(注意一:必须放在onStart方法中)
Window window = getDialog().getWindow();
if (window != null) {
// 注意二:一定要设置Background,如果不设置,window属性设置无效
window.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.white)));
WindowManager.LayoutParams layoutParams = window.getAttributes();
layoutParams.windowAnimations = R.style.MusicDialog;//动画
layoutParams.gravity = Gravity.BOTTOM; // 位置
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;//宽度满屏
window.setAttributes(layoutParams);
}
Dialog dialog = getDialog();
if (dialog != null) {
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
}
View view = inflater.inflate(R.layout.dialog_layout, container, false);
TextView mTvConfirm = ((TextView) view.findViewById(R.id.dialog_positive));
mTvConfirm.setOnClickListener(this);
return view;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.dialog_positive:
dismiss();
break;
}
}
}
效果如图:
// 0~1 , 1表示完全昏暗
dialog.getWindow().setDimAmount(0.5f);
//点击外部不消失
dialog.setCanceledOnTouchOutside(false);
//点击返回键不消失,需要监听OnKeyListener:
dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
return true;
}
return false;
}
});
//在style.xml中引入自定义动画,动画自定义
<style name="CustomDialog" parent="@android:style/Theme.Dialog">
<item name="android:windowEnterAnimation">@anim/popwin_show_anim
- "android:windowExitAnimation"
>@anim/popwin_hide_anim
style>
java代码中引用:
//在Java代码中设置窗口动画
getDialog().getWindow().getAttributes().windowAnimations = R.style.CustomDialog;
@SuppressWarnings("deprecation")
@Override
public void onStart() {
super.onStart();
Window window = getDialog().getWindow();
if (window != null) {
window.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.theme_color)));
WindowManager.LayoutParams layoutParams = window.getAttributes();
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;// 宽度满屏
layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;// 高度满屏
window.setAttributes(layoutParams);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Dialog dialog = getDialog();
if (dialog != null) {
dialog.getWindow().setDimAmount(0f);// 透明
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);// 无标题栏
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);// 解决全屏时状态栏变黑
}
View view = inflater.inflate(R.layout.main_dialog_layout, container, false);
mWebView = (WebView) view.findViewById(R.id.wv_main_dialog);
initWebSettings();
return view;
}
MainActivity传值:
MainDialogFrag mainDialogFrag = new MainDialogFrag();
Bundle bundle = new Bundle();
bundle.putString("url", mainWebDataModel.url);
bundle.putString("title", mainWebDataModel.title);
bundle.putString("msgtype", mainWebDataModel.msgtype);
mainDialogFrag.setArguments(bundle);
mainDialogFrag.show(getFragmentManager(), "MainDialogFrag");
MainDialogFrag中获取值:
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Bundle bundle = getArguments();
if (bundle != null) {
url = bundle.getString("url");
if (!TextUtils.isEmpty(url)) {
mWebView.loadUrl(url);
// mWebView.loadUrl("https://www.baidu.com/");
// mWebView.loadUrl("http://www.oschina.net/");
}
}
}
参考: Activity 与 DialogFragment 之间的数据传递
package com.example.lenovo.mydialogfrag;
import android.app.Dialog;
import android.content.DialogInterface;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
public class MyDialogFrag extends DialogFragment implements View.OnClickListener {
@Override
public void onStart() {
super.onStart();
//设置动画、位置、宽度等属性(注意一:必须放在onStart方法中)
Window window = getDialog().getWindow();
if (window != null) {
// 注意二:一定要设置Background,如果不设置,window属性设置无效
window.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.white)));
WindowManager.LayoutParams layoutParams = window.getAttributes();
layoutParams.windowAnimations = R.style.MusicDialog;//动画
layoutParams.gravity = Gravity.BOTTOM; // 位置
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;//宽度满屏
window.setAttributes(layoutParams);
}
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//去除标题栏
Dialog dialog = getDialog();
if (dialog != null) {
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
// 0~1 , 1表示完全昏暗
dialog.getWindow().setDimAmount(0.5f);
//点击外部不消失
// dialog.setCanceledOnTouchOutside(false);
//点击返回键不消失,需要监听OnKeyListener:
// dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
// @Override
// public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
// if (keyCode == KeyEvent.KEYCODE_BACK) {
// return true;
// }
// return false;
// }
// });
}
View view = inflater.inflate(R.layout.dialog_layout, container, false);
TextView mTvConfirm = ((TextView) view.findViewById(R.id.dialog_positive));
mTvConfirm.setOnClickListener(this);
return view;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.dialog_positive:
dismiss();
break;
}
}
}
dialogfragment的布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/experience_confirm_dialog_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="13dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="13dp">
<TextView
android:id="@+id/experience_confirm_dialog_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="确认消息"
android:textColor="#333333"
android:textSize="15sp" />
RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="#e6e6e6" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="20dp"
android:paddingTop="20dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/experience_confirm_dialog_msg1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="15000"
android:textColor="#ff7612"
android:textSize="18sp" />
<TextView
android:id="@+id/experience_confirm_dialog_msg2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingTop="7dp"
android:text="体验金投资额(元)"
android:textColor="#999999"
android:textSize="12sp" />
LinearLayout>
RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="#e6e6e6" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="45dp"
android:paddingLeft="20dp"
android:paddingRight="20dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="预期收益(元)"
android:textColor="#999999"
android:textSize="12sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:gravity="center"
android:text="1,000"
android:textColor="#333333"
android:textSize="12sp" />
RelativeLayout>
<TextView
android:id="@+id/dialog_positive"
android:layout_width="match_parent"
android:layout_height="43dp"
android:background="#ff7612"
android:gravity="center"
android:padding="5dp"
android:text="确定投资"
android:textColor="#ffffff"
android:textSize="18sp" />
LinearLayout>
res/value/styles
push_top_in.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:duration="10"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="-3" />
<translate
android:duration="@android:integer/config_shortAnimTime"
android:fromYDelta="-150%"
android:interpolator="@android:interpolator/decelerate_quint"
android:toYDelta="0" />
<rotate
android:duration="10"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="150"
android:toDegrees="0" />
set>
push_bottom_out.xml
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="@android:integer/config_shortAnimTime"
android:fromYDelta="0"
android:interpolator="@android:interpolator/accelerate_quint"
android:toYDelta="100%" />
效果图:
DialogFragment去除默认标题栏并横向充满屏幕
空指针:
java.lang.NullPointerException:
Attempt to invoke virtual method
'java.lang.String android.content.Context.getPackageName()' on a null object reference
DialogFragment中直接使用getActivity返回的确是空的。
在Fragment中获取context:
@Override
public void onAttach(Activity activity) {
mContext = activity;
super.onAttach(activity);
}