最全面的DialogFragment的使用,实现DialogFragment全屏、背景透明;

时间:2024-03-17 14:38:56

Android推荐使用DialogFragment代替Dialog,好处就说一点吧,DialogFragment就是个盖在界面上的Fragment,它拥有Fragment一样的功能和生命周期,解决普通Dialog旋转屏幕后异常的问题;

使用DialogFragment实现网易云音乐下载完成全局提醒、主流APP底部选择弹框;Github DialogFragmentDemo源码  完整的代码在Github上面,欢迎Star!!!

1、使用方法一、

public class CustomViewDialog extends DialogFragment {
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.dialog_view1,container);
    }
}

//在Activity或Fragment中:

 new CustomViewDialog().show(getSupportFragmentManager(),"2\'");

2、使用方式二、

public class DialogTypeDialog extends DialogFragment {

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle("提示")
                .setMessage("重写onCreateDialog其他就和Dialog设置方式相同,可以设置view或者dialog中设置setContentView和其他事件")
                .setPositiveButton("确定", null)
                .setNegativeButton("取消", null);
        return builder.create();
    }
}

3、全屏显示Dialog:

Dialog有边距不能全屏的原因是因为源码中给Dialog的Window设置了Padding值,两种方法可以让其全屏:

①:DialogFragment全屏方式一:

   // 最主要就是这句 windowIsFloating = false 
   <style name="DialogFullScreen" parent="Theme.AppCompat.Dialog">
        <item name="android:windowIsFloating">false</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:background">@android:color/transparent</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowFullscreen">true</item>
        <item name="android:colorBackgroundCacheHint">@null</item>
    </style>
//在DialogFragment中

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(DialogFragment.STYLE_NO_TITLE,R.style.DialogFullScreen); //dialog全屏
    }

②:DialogFragment全屏方式二、

    //在DialogFragment中
     @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //去掉dialog的标题,需要在setContentView()之前
        this.getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
        Window window = this.getDialog().getWindow();
        //去掉dialog默认的padding
        window.getDecorView().setPadding(0, 0, 0, 0);
        WindowManager.LayoutParams lp = window.getAttributes();
        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
        lp.height = WindowManager.LayoutParams.MATCH_PARENT;
        window.setAttributes(lp);
        final View view = inflater.inflate(R.layout.dialog_view2, null); //自己的布局文件

        return view;
    }

4、仿网易云音乐,任务下载完毕的提示:

/**
 * CCB:顶部显示、全屏、宽度全屏、高度自定义、背景全透明;
 * 仿网易云音乐下载完成提示;
 */
public class TopDialog extends DialogFragment {

    private LinearLayout ll;
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
       View dialogView = inflater.inflate(R.layout.top_dialog,container); //显示的布局
       ll = dialogView.findViewById(R.id.mView);
       FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) ll.getLayoutParams();
       params.topMargin = getStatusBarHeight(getDialog().getContext());
       ll.setLayoutParams(params); //默认在最顶部,把状态栏部分留出来
        return dialogView;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(DialogFragment.STYLE_NO_TITLE,R.style.DialogFullScreen); //dialog全屏
    }


    @Override
    public void onStart() {
        super.onStart();
        Window window = getDialog().getWindow();
        WindowManager.LayoutParams windowParams = window.getAttributes();
        windowParams.dimAmount = 0.0f;//Dialog外边框透明
        window.setLayout(-1, -2); //高度自适应,宽度全屏
        windowParams.gravity = Gravity.TOP; //在顶部显示
        windowParams.windowAnimations = R.style.TopDialogAnimation;
        window.setAttributes(windowParams);
    }

    /**
     * 获取状态栏高度(单位:px)
     */
    public static int getStatusBarHeight(Context context) {
        Resources resources = context.getResources();
        int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
        return resources.getDimensionPixelSize(resourceId) == 0 ? 60 : resources.getDimensionPixelSize(resourceId);
    }

}

显示时从顶部向下位移、隐藏是由当前位置向上唯一、动画效果:

   //注:style中 
   <style name="TopDialogAnimation">
        <item name="android:windowEnterAnimation">@anim/dialog_top_show</item>
        <item name="android:windowExitAnimation">@anim/dialog_top_hide</item>
    </style>

//注:dialog_top_show
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="@android:integer/config_mediumAnimTime"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:fromYDelta="-100%p"
        android:toYDelta="0%p"/>
</set>

//注:dialog_top_hide
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="@android:integer/config_mediumAnimTime"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:fromYDelta="0%p"
        android:toYDelta="-100%p"/>
</set>

5、仿淘宝选择拍照或相册的底部弹框:

public class BottomDialog extends DialogFragment {

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //去掉dialog的标题,需要在setContentView()之前
        this.getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
        Window window = this.getDialog().getWindow();
        //去掉dialog默认的padding
        window.getDecorView().setPadding(0, 0, 0, 0);
        WindowManager.LayoutParams lp = window.getAttributes();
        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
        //设置dialog的位置在底部
        lp.gravity = Gravity.BOTTOM;
        //设置dialog的动画
        lp.windowAnimations = R.style.BottomDialogAnimation;
        window.setAttributes(lp);
        window.setBackgroundDrawable(new ColorDrawable());

        final View view = inflater.inflate(R.layout.dialog_view2, null);

        return view;
    }
}

淘宝选择底部弹框动画效果:

   //注:style中 
     <style name="BottomDialogAnimation">
        <item name="android:windowEnterAnimation">@anim/dialog_bottom_up</item>
        <item name="android:windowExitAnimation">@anim/dialog_bottom_down</item>
    </style>

//注:dialog_bottom_up
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="@android:integer/config_mediumAnimTime"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:toYDelta="0"
        android:fromYDelta="100%p"/>
</set>

//注:dialog_bottom_down
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="@android:integer/config_mediumAnimTime"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:fromYDelta="0"
        android:toYDelta="100%p"/>
</set>

布局文件等等的就不贴过来了,详细请看Github DialogFragmentDemo源码  完整的代码在Github上面,欢迎Star!!!