How to create a transparent activity WITHOUT windowIsFloating

后端 未结 3 755
再見小時候
再見小時候 2021-01-31 10:47

windowIsFloating while a great one stop shop for creating Dialog styled UI\'s has many ---bugs--- quirks.

The one which I\'m battling right no

3条回答
  •  被撕碎了的回忆
    2021-01-31 11:35

    The accepted answer works fine, until I need to have an EditText inside the dialog-style window, as the soft IME keyboard would not push the "dialog" up without windowIsFloating. So I have to tackle the 'bug' head-on.

    As with the case in the question, I need to have the width set to "match_parent" while the height can remain "wrap_content". Using windowIsFloating, I end up setting up a ViewTreeObserver, traverse up the view tree during layout, and force the floating window to the desired width. The approach is as follows (under onCreate() of the Activity) -

    setContentView(contentView);
    
    // set up the ViewTreeObserver
    ViewTreeObserver vto = contentView.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        int displayWidth = -1;
        DisplayMetrics metrics = null;
        View containerView = null;
    
        @Override
        public void onGlobalLayout() {            
            if (containerView == null) {
                // traverse up the view tree
                ViewParent v = contentView.getParent();
                containerView = contentView;
                while ((v != null) && (v instanceof View)) {
                    containerView = (View) v;
                    v = v.getParent();
                }
            }
            if (metrics == null) {
                metrics = new DisplayMetrics();
            }
            Display display = getWindowManager().getDefaultDisplay();
            display.getMetrics(metrics);
            if (displayWidth != metrics.widthPixels) {
                displayWidth = metrics.widthPixels;
                WindowManager.LayoutParams params = 
                        (WindowManager.LayoutParams) containerView.getLayoutParams();
                // set the width to the available width to emulate match_parent
                params.width = displayWidth;
                // windowIsFloating may also dim the background
                // do this if dimming is not desired
                params.dimAmount = 0f;
                containerView.setLayoutParams(params);
                getWindowManager().updateViewLayout(containerView, params);
            }
        }
    });
    

    This works up to Android 7 so far (even in split screen mode), but one may catch the possible cast exception for casting to WindowManager.LayoutParams in case future implementation changes, and add removeOnGlobalLayoutListener(); in an appropriate place.

提交回复
热议问题