使用 DialogFragment 创建对话框

Posted 白乾涛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用 DialogFragment 创建对话框相关的知识,希望对你有一定的参考价值。

简介

在DialogFragment产生之前,我们创建对话框一般采用AlertDialog和Dialog,DialogFragment在android 3.0时被引入,是一种特殊的Fragment,用于在Activity的内容之上展示一个模态的对话框。

使用DialogFragment来管理对话框,当旋转屏幕和按下后退键时可以更好的管理其生命周期(自动重建),它和Fragment有着基本一致的生命周期。且DialogFragment也允许开发者把Dialog作为内嵌的组件进行重用,类似Fragment可以在大屏幕和小屏幕显示出不同的效果。

传统的 AlertDialog 在屏幕旋转时,既不会保存用户输入的值,对话框也不会重建,还可能会报异常
而通过DialogFragment实现的对话框则可以完全不必考虑旋转的问题。

使用DialogFragment需要实现onCreateView或者onCreateDIalog方法。onCreateView即使用自定义的xml布局文件展示Dialog,onCreateDialog即利用AlertDialog或者Dialog创建出Dialog。

Activity

public class MainActivity extends ListActivity implements MyListener {
    private FragmentManager fm;
    private FrameLayout layout;//把DialogFragment嵌入到Activity中某个容器中
    private Fragment fragment1fragment2;//注意:只有使用onCreateView创建的对话框才有效,使用onCreateDialog创建的对话框不会显示任何内容
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        String[] array = { "在onCreateDialog中创建Dialog"//
                "在onCreateDialog中创建AlertDialog"//
                "在onCreateView中创建Dialog的View",//
                "Activity和Fragment相互通信",//
                "把DialogFragment嵌入到Activity中1""把DialogFragment嵌入到Activity中2"};
        setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1new ArrayList<String>(Arrays.asList(array))));
        layout = new FrameLayout(this);
        layout.setId(123456);//只有设置了id才能获取id
        getListView().addFooterView(layout);
        fm = getFragmentManager();
        fragment1 = DF_View.newInstance(R.layout.view2);
        fragment2 = DF_Dialog.newInstance(R.layout.view2);
    }
    private boolean b;
    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        b = !b;
        switch (position) {
        case 0://在onCreateDialog中创建Dialog,旋转屏幕后,弹出的对话框会重新创建。默认情况,点击对话框外部或按返回键时,对话框会自动消失
            if (b) DF_Dialog.newInstance(R.layout.view1).show(fm"DF_Dialog_1");
            else DF_Dialog.newInstance(R.layout.view2).show(fm"DF_Dialog_2");
            break;
        case 1://在onCreateDialog中创建AlertDialog
            if (b) DF_AlertDialog.newInstance(R.layout.view1).show(fm"DF_AlertDialog_1");
            else DF_AlertDialog.newInstance(R.layout.view2).show(fm"DF_AlertDialog_2");
            break;
        case 2://在onCreateView中创建Dialog的View
            if (b) DF_View.newInstance(R.layout.view1).show(fm"DF_View_1");
            else DF_View.newInstance(R.layout.view2).show(fm"DF_View_2");
            break;
        case 3://在onCreateView中创建Dialog的View--有bug
            DF_Communication df = DF_Communication.newInstance(new SimpleDateFormat("yyyy.MM.dd HH:mm:ss").format(new Date()));
            if (b) df.setMyListener(this);
            df.show(fm"DF_Communication");
            break;
        case 4://把DialogFragment嵌入到Activity中
            if (b) fm.beginTransaction().replace(layout.getId()fragment1).commit();
            else fm.beginTransaction().remove(fragment1).commit();
            break;
        case 5://把DialogFragment嵌入到Activity中
                //注意:只有使用onCreateView创建的对话框才有效,否则onCreateView啥都没返回,也就没什么效果
            if (b) fm.beginTransaction().replace(layout.getId()fragment2).commit();
            else fm.beginTransaction().remove(fragment2).commit();
            break;
        }
    }
    @Override
    public void onComplete(String name) {
        Toast.makeText(this"返回数据:" + name, Toast.LENGTH_SHORT).show();
    }
}

DF_Dialog

public class DF_Dialog extends DialogFragment {
    /**构造时把传入的参数带进来,注意一定要通过Bundle及setArguments传递数据*/
    public static DF_Dialog newInstance(int layoutId) {
        Bundle bundle = new Bundle();//把所有需要传递的数据都放在Bundle中
        bundle.putInt("layoutId", layoutId);
        DF_Dialog fragment = new DF_Dialog();
        fragment.setArguments(bundle);//通过setArguments把Bundle传递过去
        return fragment;
    }
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Dialog dialog = new Dialog(getActivity());
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);//设置Dialog没有标题。需在setContentView之前设置,在之后设置会报错
        dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);//设置Dialog背景透明效果
        dialog.setContentView(getArguments().getInt("layoutId"));
        return dialog;
    }
}

DF_AlertDialog

public class DF_AlertDialog extends DialogFragment {
    /**构造时把传入的参数带进来,注意一定要通过Bundle及setArguments传递数据*/
    public static DF_AlertDialog newInstance(int layoutId) {
        Bundle bundle = new Bundle();//把所有需要传递的数据都放在Bundle中
        bundle.putInt("layoutId", layoutId);
        DF_AlertDialog fragment = new DF_AlertDialog();
        fragment.setArguments(bundle);//通过setArguments把Bundle传递过去
        return fragment;
    }
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog alertDialog = new AlertDialog.Builder(getActivity()).setView(getArguments().getInt("layoutId")).create();
        alertDialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);//设置Dialog背景透明效果
        return alertDialog;
    }
}

DF_View

public class DF_View extends DialogFragment {
    /**构造时把传入的参数带进来,注意一定要通过Bundle及setArguments传递数据*/
    public static DF_View newInstance(int layoutId) {
        Bundle bundle = new Bundle();//把所有需要传递的数据都放在Bundle中
        bundle.putInt("layoutId", layoutId);
        DF_View fragment = new DF_View();
        fragment.setArguments(bundle);//通过setArguments把Bundle传递过去
        return fragment;
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Dialog dialog = getDialog();
        if (dialog != null) {//有些场景下是获取不到的
            dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);//设置Dialog没有标题。需在setContentView之前设置,在之后设置会报错
            dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);//设置Dialog背景透明效果
        }
        return inflater.inflate(getArguments().getInt("layoutId")null);
    }
}

DF_Communication

public class DF_Communication extends DialogFragment implements OnClickListener {
    private EditText mUsername;
    public static DF_Communication newInstance(String name) {
        Bundle bundle = new Bundle();
        bundle.putString("name", name);
        DF_Communication fragment = new DF_Communication();
        fragment.setArguments(bundle);
        return fragment;
    }
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        View view = getActivity().getLayoutInflater().inflate(R.layout.view2null);
        mUsername = (EditText) view.findViewById(R.id.et_username);
        mUsername.setText(getArguments().getString("name"));
        view.findViewById(R.id.iv_head).setOnClickListener(this);
        AlertDialog alertDialog = new AlertDialog.Builder(getActivity()).setView(view).create();
        alertDialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);//设置Dialog背景透明效果
        return alertDialog;
    }
    @Override
    public void onDismiss(DialogInterface dialog) {
        super.onDismiss(dialog);
        if (listener != null) listener.onComplete(mUsername.getText().toString());
    }
    //******************************************************************************************
    private MyListener listener;
    public MyListener getMyListener() {
        return listener;
    }
    public void setMyListener(MyListener listener) {
        this.listener = listener;
    }
    @Override
    public void onClick(View paramView) {
        if (listener != null) listener.onComplete(mUsername.getText().toString());
    }
}

MyListener 

public interface MyListener {
    public void onComplete(String username);
}

附件列表

     

    以上是关于使用 DialogFragment 创建对话框的主要内容,如果未能解决你的问题,请参考以下文章

    使用DialogFragment创建自定义对话框

    Android 官方推荐 : DialogFragment 创建对话框

    Android 官方推荐 : DialogFragment 创建对话框

    text 三句代码创建全屏对话框或者DialogFragment

    通过 findFragmentByTag 从 FragmentManager 获取 DialogFragment

    Android为啥推荐用DialogFragment创建Dialog?