当前位置: 首页 > 工具软件 > XY_Dialog > 使用案例 >

[原创]用代码dialog 高度 宽度无法屏幕屏幕问题

韦安顺
2023-12-01

不做笔记全给忘记了,因为百度都是不靠谱的答案,所以探索出来的东西还是发不出来笔记号

public static <T extends ViewDataBinding> Pair<Dialog,T> getDialog(Context context, @LayoutRes int layout, Class<T> parent_, ViewGroup viewGroup) {
        Dialog dialog = new Dialog(context);


        Window window = dialog.getWindow();
        WindowManager.LayoutParams lp = window.getAttributes();
        window.getDecorView().setPadding(0, 0, 0, 0);
        lp.dimAmount = 0;//dimAmount在0.0f和1.0f之间,0.0f完全不暗,1.0f全暗
        lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
        lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
        lp.gravity = Gravity.TOP;
        dialog.getWindow().setAttributes(lp);
        dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        
        dialog.getWindow().setBackgroundDrawable(null);
        T dataBinding = DataBindingUtil.inflate(LayoutInflater.from(context),layout, viewGroup, false);
//        dialog.getWindow().setBackgroundDrawableResource(android.R.color.white);
        /*
           <item name="android:windowFrame">@null</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:windowIsTranslucent">false</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowBackground">@android:color/white</item>
        <item name="android:backgroundDimEnabled">true</item>

         */
        dialog.setContentView(dataBinding.getRoot());

        dialog.setCanceledOnTouchOutside(true);
        return new Pair<>(dialog,dataBinding);
    }

包含修改状态栏颜色

@SuppressLint("WrongConstant")
    public static <T extends ViewDataBinding> Pair<Dialog,T> getDialog(Context context, @LayoutRes int layout, Class<T> parent_, ViewGroup viewGroup) {
        Dialog dialog = new Dialog(context);



        Window window = dialog.getWindow();
        WindowManager.LayoutParams lp = window.getAttributes();
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0 全透明实现
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(AppContext.getInstance().getResources().getColor(R.color.themeColor));

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
//                lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
            }

        } else {//4.4 全透明状态栏
//            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//不需要透明
        }

        window.getDecorView().setPadding(0, window.getDecorView().getPaddingTop(), 0, 0);
        lp.dimAmount = 0;//dimAmount在0.0f和1.0f之间,0.0f完全不暗,1.0f全暗
        lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
        lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
        lp.gravity = Gravity.BOTTOM;
        dialog.getWindow().setAttributes(lp);
        dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.WHITE));
        T dataBinding = DataBindingUtil.inflate(LayoutInflater.from(context),layout, viewGroup, false);
        dialog.setContentView(dataBinding.getRoot());
        dialog.setCanceledOnTouchOutside(true);
        return new Pair<>(dialog,dataBinding);
    }
public static void setTranslucentStatus(Activity activity) {
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0 全透明实现
            Window window = activity.getWindow();
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(Color.TRANSPARENT);
        } else {//4.4 全透明状态栏
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
    }

后面pad遇到了一些问题
下面3 三种对话框全屏的实现方法

/**
     * 
     * 设置了View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR 状态栏为白色,字体为黑色 pad上也无bug,自动padding状态栏  SYSTEM_UI_FLAG_HIDE_NAVIGATION 解决pad 导航栏透明看不见以及布局延伸到状态栏问题,但是需要解决一个问题。状态栏变指定颜色
     * @param context
     * @param layout
     * @param parent_ 只是用来防止强转的麻烦
     * @param viewGroup
     * @param <T>
     * @return
     */
    @SuppressLint("WrongConstant")
    public static <T extends ViewDataBinding> Pair<Dialog,T> getDialog(Context context, @LayoutRes int layout, Class<T> parent_, ViewGroup viewGroup) {
        Dialog dialog = new Dialog(context);
        Window window = dialog.getWindow();
        WindowManager.LayoutParams lp = window.getAttributes();
        //如果不高亮 就去掉    window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0 全透明实现
            window.getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);// View.SYSTEM_UI_FLAG_LAYOUT_STABLE|
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);//不设置无法修改状态栏颜色,但是能解决pad上布局被延到状态栏问题
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS );//如果要设置栏颜色自定义必须没有设置 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 不设置状态栏将变成透明自定义颜色设置无效[pad已验证]            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);//如果要设置栏颜色自定义必须没有设置 ,SYSTEM_UI_FLAG_LAYOUT_STABLE可有可无。
            window.setStatusBarColor(AppContext.getInstance().getResources().getColor(R.color.themeColor));
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
//                lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
//                lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
            }
//https://www.jianshu.com/p/50d2024fa60a
        } else {//4.4 全透明状态栏
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//不需要透明
        }
        window.getDecorView().setPadding(0, 0, 0, 0);
        lp.dimAmount = 0;//dimAmount在0.0f和1.0f之间,0.0f完全不暗,1.0f全暗
        lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
        lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
        lp.gravity = Gravity.BOTTOM;
        dialog.getWindow().setAttributes(lp);
        dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.WHITE));
        T dataBinding = DataBindingUtil.inflate(LayoutInflater.from(context),layout, viewGroup, false);
        dialog.setContentView(dataBinding.getRoot());
        dialog.setCanceledOnTouchOutside(true);
        return new Pair<>(dialog,dataBinding);
    }

    /**
     * 在pad 布局会衍生到状态栏,需要手动处理 给状态栏高度填充自己的一块任意颜色view.
     * @param context
     * @param layout
     * @param parent_
     * @param viewGroup
     * @param <T>
     * @return
     */
    public static <T extends ViewDataBinding> Pair<Dialog,T> getFullDialog(Context context, @LayoutRes int layout, Class<T> parent_, ViewGroup viewGroup) {
//全屏对话框 https://blog.csdn.net/qijingwang/article/details/118368281
        AppCompatDialog dialog = new AppCompatDialog(context, R.style.ThemeOverlay_AppCompat_Dialog);

        dialog.supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
        T dataBinding = DataBindingUtil.inflate(LayoutInflater.from(context),layout, viewGroup, false);
        dialog.setContentView(dataBinding.getRoot());
        Window window = dialog.getWindow();
        window.getDecorView().setFitsSystemWindows(true);
        window.getDecorView().setPadding(0,0, 0, 0);//不设置虽然是白色背景,但是无法铺满。
        WindowManager.LayoutParams lp = window.getAttributes();
        lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
        lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
        lp.gravity = Gravity.BOTTOM;
        dialog.getWindow().setAttributes(lp);
        dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.WHITE));
        dialog.setCanceledOnTouchOutside(true);
        modifyDialogStatusBar(dialog,AppContext.getInstance().getResources().getColor(R.color.themeColor));
        //修改参数属性必须设置在后面,但是虽然全屏了,但是状态栏颜色变了
        return new Pair<>(dialog,dataBinding);
    }
    @SuppressLint("WrongConstant")
    public static void modifyDialogStatusBar(Dialog dialog, @ColorInt int color){
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0 全透明实现
            Window window = dialog.getWindow();
//            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);

            //decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); 状态栏宝妞 如果不加SYSTEM_UI_FLAG_LAYOUT_STABLE直接全屏。状态栏遮盖
            //布局衍生到导航栏 .SYSTEM_UI_FLAG_HIDE_NAVIGATION和SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(color);
//            window.setStatusBarColor(color);
            WindowManager.LayoutParams lp = dialog.getWindow().getAttributes();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
//                lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
//                lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;//这导致状态栏变白色不会变成默认修改的颜色, ,导致上面设置的颜色无效,
            }
            dialog.getWindow().setAttributes(lp);


        } else {//4.4 全透明状态栏
            dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
    }

    /**
     * 这种方式全屏有缺陷,会导致很容易滑动下来
     * @param context
     * @param layout
     * @param parent_
     * @param viewGroup
     * @param <T>
     * @return
     */
    public static <T extends ViewDataBinding> Pair<Dialog,T> getBottomSheetFullDialog(Context context, @LayoutRes int layout, Class<T> parent_, ViewGroup viewGroup) {

        BottomSheetDialog dialog = new BottomSheetDialog(context){
            @Override
            public void show() {
                super.show();
                View mContent = getWindow().getDecorView().findViewById(R.id.design_bottom_sheet);
                ViewGroup.LayoutParams orginLayoutParams = mContent.getLayoutParams();
                orginLayoutParams.height=ViewGroup.LayoutParams.MATCH_PARENT;
                mContent.setLayoutParams(orginLayoutParams);
                BottomSheetBehavior<View> from = BottomSheetBehavior.from(mContent);
                from.setState(BottomSheetBehavior.STATE_EXPANDED);
            }
        };
        Window window = dialog.getWindow();
        WindowManager.LayoutParams lp = window.getAttributes();
        dialog.getWindow().setAttributes(lp);
        T dataBinding = DataBindingUtil.inflate(LayoutInflater.from(context),layout, viewGroup, false);
        dialog.setContentView(dataBinding.getRoot());
        dialog.setCanceledOnTouchOutside(true);
        return new Pair<>(dialog,dataBinding);
    }

pad上状态栏被填充的问题
如果是toolbar,那就把toolbar的padding多设置一点

int[] position=new int[2];
                dialogPair.second.getRoot().getLocationOnScreen(position);
                if (position[0] == 0) {
                    int statusBarHeight = AppUtils.getStatusBarHeight(getThis());
//                    FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
                    dialogPair.second.toolbar.setPadding(0,statusBarHeight,0,0);//处理pad 布局填充到状态栏问题
                }

或者自定义一个view到状态栏
这个问题只有在pad上自定义状态栏颜色才会出现

int[] position = new int[2];
                    dataBinding.getRoot().getLocationOnScreen(position);
                    if (position[0] == 0) {
                        int statusBarHeight = AppUtils.getStatusBarHeight(getThis());
                        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
                        params.topMargin = statusBarHeight;
                        View view = new View(dataBinding.getRoot().getContext());
                        view.setBackgroundColor(getThis().getResources().getColor(R.color.themeColor));
                        ViewGroup viewGroup = (ViewGroup) dataBinding.getRoot();
                        viewGroup.addView(view, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, AppUtils.getStatusBarHeight(getThis())));
                        dataBinding.nestedScrollView.setPadding(0,statusBarHeight,0,0);//解决直接到顶问题。
                        dataBinding.btnClose.setPadding(dataBinding.btnClose.getPaddingLeft(),dataBinding.btnClose.getPaddingTop()+statusBarHeight,dataBinding.btnClose.getPaddingRight(),dataBinding.btnClose.getPaddingBottom());
                    }

上面修复状态栏代码在show之后使用

上面代码使用x y为0 这就解决了getLocationOnScreen()获取时机不对导致为0 问题。

dataBinding.getRoot().addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
                    @Override
                    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                        int[] position = new int[2];
                        dataBinding.getRoot().getLocationOnScreen(position);
                            int statusBarHeight = position[1] == 0?AppUtils.getStatusBarHeight(getThis()):0;
                            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
                            params.topMargin = statusBarHeight;
                            View view = new View(dataBinding.getRoot().getContext());
                            view.setBackgroundColor(getThis().getResources().getColor(R.color.themeColor));
                            ViewGroup viewGroup = (ViewGroup) dataBinding.getRoot();
                            viewGroup.addView(view, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, AppUtils.getStatusBarHeight(getThis())));
                            dataBinding.nestedScrollView.setPadding(0, statusBarHeight, 0, 0);//解决直接到顶问题。
                            dataBinding.btnClose.setPadding(dataBinding.btnClose.getPaddingLeft(), dataBinding.btnClose.getPaddingTop() + statusBarHeight, dataBinding.btnClose.getPaddingRight(), dataBinding.btnClose.getPaddingBottom());
                        Log.w("XY", Arrays.toString(position));
                    }
                });
 类似资料: