Android中DialogFragment的简单使用及常见问题

关于DialogFragment实现自定义对话框样式及遇到的问题(主要是宽度的),这里记录一下。

一.先写一个自定义的Dialog布局,布局就是普通的xml,想怎么写就怎么写(注意整体大小),以下使用R.layout.dialog_submit_product_t0代替

二.写一个自定义类继承DialogFragment,接下来就和普通Fragment没什么区别了

public class CustomeDialogFragment extends DialogFragment implements View.OnClickListener {
    private View view = null;
    private ImageView mCloseImg;
    private Button mConfirmBtn;

    /**
     * 静态方法产生实例
     * @return
     */
    public static CustomeDialogFragment getInstance(){
        CustomeDialogFragment customeDialogFragment = new CustomeDialogFragment();
        return customeDialogFragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
        getDialog().setOnKeyListener(new DialogInterface.OnKeyListener() {
            @Override
            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
                    dismiss();
                    return true; // pretend we've processed it
                } else
                    return false; // pass on to be processed as normal
            }
        });
        view = inflater.inflate(R.layout.dialog_submit_product_t0,container,false);
        mCloseImg = view.findViewById(R.id.dialog_close);
        mCloseImg.setOnClickListener(this);
        mConfirmBtn = view.findViewById(R.id.dialog_product_confirm_btn);
        mConfirmBtn.setOnClickListener(this);

        return view;
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setCancelable(false);//无法直接点击外部取消dialog
        //setStyle(DialogFragment.STYLE_NORMAL,0);//NO_FRAME就是dialog无边框,0指的是默认系统Theme
        setStyle(DialogFragment.STYLE_NO_TITLE, android.R.style.Theme_Holo_Light_Dialog_MinWidth);
    }

    @Override
    public void onStart() {
        super.onStart();
        Dialog dialog = getDialog();
        if (dialog != null) {
            DisplayMetrics dm = new DisplayMetrics();
            getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
            dialog.getWindow().setLayout((int) (dm.widthPixels * 0.9), ViewGroup.LayoutParams.WRAP_CONTENT);
        }
    }

    @Override
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.dialog_close:
                dismiss();

                break;

            case R.id.dialog_product_confirm_btn:
                Toast.makeText(getActivity(),"点击确定",Toast.LENGTH_SHORT).show();
                dismiss();

                break;
        }

    }
}

三.在需要弹出Dialog的地方:

 CustomeDialogFragment dialogFragment = CustomeDialogFragment.getInstance();
 FragmentTransaction ft = getFragmentManager().beginTransaction();
 dialogFragment.show(ft, "dialogFragment");

就这么简单,比自定义Dialog简单多了,更关键的是不会随着手机系统版本改变Dialog样式。

接下来谈谈遇到的一些问题和解决方法:

1.如果需要无法直接点击外部取消Dialog:

onCreate中:

    setCancelable(false);//无法直接点击外部取消dialog  

但这样做连点击返回键都无法将Dialog取消,显然不好,那就需要在onCreateView中加上监听返回键的代码:

getDialog().setOnKeyListener(new DialogInterface.OnKeyListener() {
            @Override
            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
                    dismiss();
                    return true; // pretend we've processed it
                } else
                    return false; // pass on to be processed as normal
            }
        });

2.DialogFragment背景不变暗
如果我们定义了整个项目的style,有可能就会遇到DialogFragment背景不变暗的情况,这时只需要为DialogFragment设置style就好了,在自定义DialogFragement的onCreate中:

setStyle(DialogFragment.STYLE_NO_FRAME, R.style.Theme_Dialog_Fragment);  

在style中加上

<style name="Theme_Dialog_Fragment" parent="android:style/Theme.Dialog">  
        <item name="android:backgroundDimEnabled">true</item> //背景变暗  
</style> 

3.DialogFragment黑边或者白边问题

弹出的dialog虽然是自定义样式,但边框会有黑边或者白边,解决方法:

在自定义DialogFragement的onCreateView方法中:

this.getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); //设置dialog的背景为透明  

4.如果对话框不能有标题,则在onCreateView中

getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);

5.有时候想要是能让对话框占用固定比例的屏幕宽度会显得更美观一些。

使对话框充满屏幕宽度
这时候可以在onCreate中

setStyle(DialogFragment.STYLE_NO_TITLE, android.R.style.Theme_Holo_Light_Dialog_MinWidth);

这里设置了无标题样式(此时onCreateView的getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);就没有必要了,可以删掉了),并保证对话框的最小宽度

(2)占用屏幕宽度一定比例
另外一种方式,这种方式是自己计算屏幕宽度并设置到对话框,重写onStart方法,实现如下

 @Override
    public void onStart() {
        super.onStart();
        Dialog dialog = getDialog();
        if (dialog != null) {
            DisplayMetrics dm = new DisplayMetrics();
            getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
            dialog.getWindow().setLayout((int) (dm.widthPixels * 0.9), ViewGroup.LayoutParams.WRAP_CONTENT);
        }
    }

从代码可以看出,首先计算屏幕的宽度,然后将宽度的75%设置到对话框的Window上,高度为WRAP_CONTENT。
记得要在onCreateView方法中加上

getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);

对话框圆角

如果要实现自定义对话框圆角,可以加入下面的代码使对话框背景透明

getDialog().getWindow().setBackgroundDrawableResource(android.R.color.transparent);

然后将自定义布局设置为圆角就可以了,在drawable目录中定义XML如下

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="8dp"/>
    <stroke android:color="#FDFFFFFF"/>
    <solid android:color="#FDFFFFFF"/>
</shape>

然后将自定义布局的根布局background属性设置为该xml就可以了。
参考
http://blog.csdn.net/zhyh1986/article/details/48655885

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章