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

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