DialogFragment在android3.0时被引入。是一种特殊的Fragament,用于在Activity的内容之上展示一个模态的对话框。
DialogFragment与Fragment有着基本一致的生命周期,允许开发者将Dialog或AlertDialog内嵌进行重用,最少需要实现onCreateView()或onCreateDialog()。
onCreateView()可以设置xml布局创建一个Dialog;onCreateDialog()可以自定义创建一个Dialog或AlertDialog自定义对话框。
- dialog_custom_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- 标题 -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:gravity="center"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:text="@string/app_name"
android:textColor="@android:color/white" />
<EditText
android:id="@+id/et_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="input username"
android:inputType="text"
android:padding="10dp" />
<EditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="input password"
android:inputType="textPassword"
android:padding="10dp" />
<!-- 取消和确定按钮 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btn_cancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="cancel"/>
<Button
android:id="@+id/btn_confirm"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="confirm"/>
</LinearLayout>
</LinearLayout>
- BaseDialog.java
package com.example.dialogfragment.dialog;
import android.app.Dialog;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.RelativeLayout;
import butterknife.Unbinder;
/**
* 使用DialogFragment创建对话框有三种方式:
* 1、使用DialogFragment提供的Dialog,只在onCreateView()中提供对话框的布局(包括对话框按钮)
* 2、在onCreateDialog()中创建自定义Dialog返回,比如AlertDialog(AlertDialog不用在布局加标题,除非dialog.setView(view))
* 3、结合onCreateView()提供对话框布局,onCreateDialog()创建自定义Dialog
*
* 该例子使用第三种方式创建,onCreateView()提供对话框布局,onCreateDialog()创建自定义Dialog
*/
public abstract class BaseDialog extends DialogFragment {
private Unbinder mUnBinder;
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
RelativeLayout root = new RelativeLayout(getActivity());
root.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
Dialog dialog = new Dialog(getContext());
// 去除对话框默认标题
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
// 设置焦点监听
dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
return onKeyListener(dialog, keyCode, event);
}
});
dialog.setContentView(root);
if (dialog.getWindow() != null) {
// 透明背景,如果设置需要自定义dialog的布局自己提供背景颜色
// 设置了透明背景,布局与屏幕横向将没有边距
// dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
// 设置对话框横向全屏,纵向自适应高度
dialog.getWindow().setLayout(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
dialog.setCanceledOnTouchOutside(false);
return dialog;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setUp(view);
}
@Override
public void show(FragmentManager manager, String tag) {
FragmentTransaction transaction = manager.beginTransaction();
Fragment fragment = manager.findFragmentByTag(tag);
// 如果已经有这个dialog,则先移除,创建一个新的,每个dialog都要提供一个tag存入FragmentManager
if (fragment != null) {
transaction.remove(fragment);
}
transaction.addToBackStack(null);
show(transaction, tag);
}
@Override
public void onDestroyView() {
if (mUnBinder != null) {
mUnBinder.unbind();
}
super.onDestroyView();
}
protected void setUnBinder(Unbinder unBinder) {
mUnBinder = unBinder;
}
protected boolean onKeyListener(DialogInterface dialog, int keyCode, KeyEvent event) {
return false;
}
/**
* 对话框创建后,在该方法修改对话框布局的某些view
*/
protected abstract void setUp(View view);
}
- MyDialog.java
package com.example.dialogfragment.dialog;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import com.example.dialogfragment.R;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class MyDialog extends BaseDialog {
public static final String TAG = MyDialog.class.getSimpleName();
@BindView(R.id.et_name)
EditText mEtName;
@BindView(R.id.et_password)
EditText mEtPassword;
@BindView(R.id.btn_cancel)
Button mBtnCancel;
@BindView(R.id.btn_confirm)
Button mBtnConfirm;
@OnClick(R.id.btn_cancel)
public void cancel() {
dismiss();
if (mListener != null) {
mListener.onNegativeClick();
}
}
@OnClick(R.id.btn_confirm)
public void confirm() {
dismiss();
if (mListener != null) {
mListener.onPositiveClick();
String name = mEtName.getText().toString().trim();
String password = mEtPassword.getText().toString().trim();
mListener.onEditInput(name, password);
}
}
public static MyDialog newInstance() {
MyDialog fragment = new MyDialog();
Bundle bundle = new Bundle();
fragment.setArguments(bundle);
return fragment;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.dialog_custom_layout, container, false);
setUnBinder(ButterKnife.bind(this, view));
return view;
}
@Override
protected void setUp(View view) {
mBtnCancel.setText("cancel change");
mBtnConfirm.setText("confirm change");
}
public interface OnDialogListener {
void onNegativeClick();
void onPositiveClick();
void onEditInput(String name, String password);
}
private OnDialogListener mListener;
public MyDialog setDialogListener(OnDialogListener listener) {
mListener = listener;
return this;
}
}
- MainActivity.java
package com.example.dialogfragment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
import com.example.dialogfragment.dialog.MyDialog;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;
public class MainActivity extends AppCompatActivity {
private Unbinder mUnBinder;
@OnClick(R.id.btn_dialog)
public void showDialog() {
MyDialog.newInstance().setDialogListener(new MyDialog.OnDialogListener() {
@Override
public void onNegativeClick() {
}
@Override
public void onPositiveClick() {
}
@Override
public void onEditInput(String name, String password) {
Toast.makeText(MainActivity.this, "name:" + name + ", password:" + password, Toast.LENGTH_LONG).show();
}
}).show(getSupportFragmentManager(), MyDialog.TAG);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mUnBinder = ButterKnife.bind(this);
}
@Override
protected void onDestroy() {
if (mUnBinder != null) {
mUnBinder.unbind();
}
super.onDestroy();
}
}