Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

冷知识——解决模态框弹框破坏沉浸式全屏模式 #65

Open
soapgu opened this issue Jul 26, 2021 · 0 comments
Open

冷知识——解决模态框弹框破坏沉浸式全屏模式 #65

soapgu opened this issue Jul 26, 2021 · 0 comments
Labels
problem problem or trouble 安卓 安卓

Comments

@soapgu
Copy link
Owner

soapgu commented Jul 26, 2021

  • 妖孽的bug

目前把安卓的App的界面以全屏模式现实,不现实上方状态栏和下方的导航栏已经没有问题。一次无意的操作发现,突然上方的状态栏出现了。后经过反正验证,发现和模态框有关,一开始并没多在意,以为是个别样式设置问题。后面发现只要是模态框就会破坏全屏沉浸式模式。

  • 问题解决定位

这个问题比较棘手,官网似乎并没有提到。属于小小冷门,百度出的解决方案也是语焉不详,想这种解决针对性问题还是StackOverflow最靠谱

How do I maintain the Immersive Mode in Dialogs?

  • 相关代码

  1. 原生Dialog的相关处理
/**
 * 模态框相关方法
 */
public abstract class DialogFns {

    /**
     * 沉浸式显示模态框
     * @param dialog 模态框
     * @param context 当前调用端Activity
     */
    public static void showImmersive(Dialog dialog, Activity context){
        //Here's the magic..
        //Set the dialog to not focusable (makes navigation ignore us adding the window)
        dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);

        //Set the dialog to immersive
        dialog.getWindow().getDecorView().setSystemUiVisibility(
                context.getWindow().getDecorView().getSystemUiVisibility());

        //Show the dialog! (Hopefully no soft navigation...)
        dialog.show();

        //Clear the not focusable flag from the window
        dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
    }
}

调用部分

AlertDialog exitDialog = new AlertDialog.Builder(this.requireContext())
                    .setTitle("退出")
                    .setMessage("请确认是否退出")
                    .setPositiveButton("是", (dialog, which) -> {
                        dialog.dismiss();
                        Context context = requireContext();
                        context.sendBroadcast(new Intent("com.android.systemui.SHOW_NAVIGATION_BAR"));
                        context.sendBroadcast(new Intent("com.android.showNavBar"));
                        String packageName = this.requireContext().getPackageName();
                        String command = String.format("am force-stop %s", packageName);
                        Logger.w("-----this application %s will be killed----", packageName);
                        ShellFns.excuteSlient(command);
                    })
                    .setNegativeButton("否", null)
                    .create();
            //exitDialog.show();
            DialogFns.showImmersive( exitDialog,requireActivity() );
  1. DialogFragment的处理

DialogFragment的内部实现也是Dialog,原理上是一样的,代码处理不同。

public class MVVMDialogFragment<VM extends ViewModel> extends DialogFragment {
    ...

    /**
     * 设置是否沉浸模式,默认是
     * 派生类可以改写此方法
     * @return 是否全屏
     */
    protected boolean showImmersive(){
        return true;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if( showImmersive() ) {
            requireDialog().getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
            requireDialog().getWindow().getDecorView().setSystemUiVisibility(requireActivity().getWindow().getDecorView().getSystemUiVisibility());

            requireDialog().setOnShowListener(dialog -> {
                //Clear the not focusable flag from the window
                requireDialog().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
            });
        }
        ...
    }
}
  • 总结部分

代码重点就是

  • 把Dialog对应的Window设置上FLAG_NOT_FOCUSABLE标记
  • setSystemUiVisibility和当前的的Activity的值一模一样
  • 调用show
  • show调用完成后,把 FLAG_NOT_FOCUSABLE标记取消

经过测试可行

@soapgu soapgu changed the title app实现Android系统重启的两种方法 留白,换其他技术博客 Jul 26, 2021
@soapgu soapgu changed the title 留白,换其他技术博客 冷知识——解决模态框弹框破坏沉浸式全屏模式 Jul 29, 2021
@soapgu soapgu added problem problem or trouble 安卓 安卓 labels Jul 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
problem problem or trouble 安卓 安卓
Projects
None yet
Development

No branches or pull requests

1 participant