DialogFragment更優雅的使用

DialogFragment在android 3.0時被引入。是一種特殊的Fragment,用於在Activity的內容之上展示一個模態的對話框。

1.官方這樣介紹的:

A fragment that displays a dialog window, floating on top of its activity’s window. This fragment contains a Dialog object, which it displays as appropriate based on the fragment’s state. Control of the dialog (deciding when to show, hide, dismiss it) should be done through the API here, not with direct calls on the dialog.
一個顯示Dialog(對話框窗口)的Fragment(碎片,片段),懸浮在當前Activity(活動)窗口之上,這個Fragment包含一個Dialog(對話框窗口)對象,它根據Fragment的狀態顯示合適的內容,根據提供的API控制這個Dialog的顯示,隱藏,解散。而不是直接調用這個Dialog

2.繼承以及實現類結構:

  public class DialogFragment extends Fragment implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener 

DialogFragment提供了四種默認樣式

    /**
     * 一個基礎的,正常樣式的dialog.
     */
    public static final int STYLE_NORMAL = 0;

    /**
     * 這個樣式不包括標題區。
     */
    public static final int STYLE_NO_TITLE = 1;

    /**
     * 這個樣式無任何框架,在onCreateView()中進行繪製視圖。
     */
    public static final int STYLE_NO_FRAME = 2;

    /**
     * 禁用所有輸入對話框。用戶不能觸摸它,它的窗口將不能接收輸入焦點。
     */
    public static final int STYLE_NO_INPUT = 3;

3.對DialogFragment進行封裝,使用更加方便

  • 定義一個默認主題
    <style name="default_dialog_style" parent="@android:style/Theme.Dialog">
        <item name="android:windowFrame">@null</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
    </style>
  • 這裏爲了方便直接使用STYLE_NO_FRAME樣式,具體封裝如下:
package com.common.base;

import android.app.Activity;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;

import com.common.R;

/**
 * 作者:秦川小將
 * 時間:2017/8/14
 * 描述:基類Dialog
 */
public abstract class BaseDialog extends DialogFragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 設置自定義樣式
        if (setDialogStyle() == 0) {
            setStyle(DialogFragment.STYLE_NO_FRAME, R.style.default_dialog_style);
        } else {
            setStyle(DialogFragment.STYLE_NO_FRAME, setDialogStyle());
        }
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        // 設置進場動畫
        if (setWindowAnimationsStyle() != 0) {
            getDialog().getWindow().setWindowAnimations(setWindowAnimationsStyle());
        }
        // return 視圖
        View mView = null;
        if (mView == null) {
            mView = inflater.inflate(getLayoutId(), container, false);
        } else {
            if (mView != null) {
                ViewGroup mViewGroup = (ViewGroup) mView.getParent();
                if (mViewGroup != null) {
                    mViewGroup.removeView(mView);
                }
            }
        }
        return mView;
    }


    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        initView(view);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        loadData(getArguments());
    }

    /**
     * 自定義時添加layout
     *
     * @return
     */
    protected abstract int getLayoutId();

    /**
     * 初始化
     *
     * @param view
     */
    protected abstract void initView(View view);


    /**
     * 加載數據
     *
     * @param bundle 用這個Bundle對象接收傳入時的Bundle對象
     */
    protected abstract void loadData(Bundle bundle);

    /**
     * 創建視圖
     *
     * @param context
     * @param resId
     * @param <T>
     * @return
     */
    protected <T extends View> T createView(Context context, int resId) {
        return (T) LayoutInflater.from(context).inflate(resId, null);
    }

    /**
     * 設置Dialog點擊外部區域是否隱藏
     *
     * @param cancel
     */
    protected void setCanceledOnTouchOutside(boolean cancel) {
        if (getDialog() != null) {
            getDialog().setCanceledOnTouchOutside(cancel);
        }
    }

    /**
     * 設置Dialog gravity
     *
     * @param gravity
     */
    protected void setGravity(int gravity) {
        if (getDialog() != null) {
            Window mWindow = getDialog().getWindow();
            WindowManager.LayoutParams params = mWindow.getAttributes();
            params.gravity = gravity;
            mWindow.setAttributes(params);
        }
    }

    /**
     * 設置Dialog窗口width
     *
     * @param width
     */
    protected void setDialogWidth(int width) {
        setDialogWidthAndHeight(width, LinearLayout.LayoutParams.WRAP_CONTENT);
    }

    /**
     * 設置Dialog窗口height
     *
     * @param height
     */
    protected void setDialogHeight(int height) {
        setDialogWidthAndHeight(LinearLayout.LayoutParams.WRAP_CONTENT, height);
    }

    /**
     * 設置Dialog窗口width,height
     *
     * @param width
     * @param height
     */
    protected void setDialogWidthAndHeight(int width, int height) {
        if (getDialog() != null) {
            getDialog().getWindow().setLayout(width, height);
        }
    }

    /**
     * 設置窗口轉場動畫
     *
     * @return
     */
    protected int setWindowAnimationsStyle() {
        return 0;
    }

    /**
     * 設置彈出框樣式
     *
     * @return
     */
    protected int setDialogStyle() {
        return 0;
    }


    /**
     * 顯示Dialog
     *
     * @param activity
     * @param tag      設置一個標籤用來標記Dialog
     */
    public void show(Activity activity, String tag) {
        show(activity, null, tag);
    }

    /**
     * 顯示Dialog
     *
     * @param activity
     * @param bundle   要傳遞給Dialog的Bundle對象
     * @param tag      設置一個標籤用來標記Dialog
     */
    public void show(Activity activity, Bundle bundle, String tag) {
        if (activity == null && isShowing())
            return;
        FragmentTransaction mTransaction = activity.getFragmentManager().beginTransaction();
        Fragment mFragment = activity.getFragmentManager().findFragmentByTag(tag);
        if (mFragment != null) {
            //爲了不重複顯示dialog,在顯示對話框之前移除正在顯示的對話框
            mTransaction.remove(mFragment);
        }
        if (bundle != null) {
            setArguments(bundle);
        }
        show(mTransaction, tag);
    }

    /**
     * 是否顯示
     *
     * @return false:isHidden  true:isShowing
     */
    protected boolean isShowing() {
        if (this.getDialog() != null) {
            return this.getDialog().isShowing();
        } else {
            return false;
        }
    }
}
  • 使用
public class SampleDialog extends BaseDialog {

    public static final String PHONE = "phone";
    private TextView mPhoneText;
    private String mPhone;

    public static SampleDialog newInstance(String phone) {
        SampleDialog mDialog = new SampleDialog ();
        Bundle mBundle = new Bundle();
        mBundle .putString(PHONE, phone);
        mDialog.setArguments(args);
        return mDialog;
    }

    @Override
    protected int getLayoutId() {
        return R.layout.dialog_service_phone;
    }

    @Override
    protected void initView(View view) {
        mPhoneText = (TextView) view.findViewById(R.id.dialog_service_phone_tv);
        /** 其他操作 **/
    }

    @Override
    protected void loadData(Bundle bundle) {
        if (bundle != null) {
            mPhone = bundle.getString(PHONE, "");
        }
        mPhoneText.setText(mPhone);
    }

    public void show(Activity activity) {
        show(activity, "PhoneDialog");
    }
}
    // 其他地方調用
    SampleDialog.newInstance("182*****008");

4.設置Dialog寬高(Width,Height)

對DialogFragment設置寬高時在View初始完成後或者窗口展示出來時進行設置,也可參考如下:

    @Override
    public void onResume() {
        super.onResume();
        setDialogWidth(DeviceUtils.getScreenWidth(getActivity()) - DeviceUtils.dp2px(getActivity(), 200));
    }
  // DeviceUtils.getScreenWidth(getActivity())爲獲取到的當前屏幕寬度
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章