How to set margins to a custom dialog?

前端 未结 15 1202
再見小時候
再見小時候 2020-12-05 05:56

Does anybody knows how can I set margins to a custom dialog? I\'m asking because I\'ve a custom dialog but when displayed it stretches to fill the parent, even though I set

15条回答
  •  自闭症患者
    2020-12-05 06:47

    This is a straight-forward, programmatic way to set position and size of my dialog with margins.

    I tested my approach for a DialogFragment by applying it in the onCreateDialog method:

    public Dialog onCreateDialog( Bundle savedInstanceState )
    {
        // create dialog in an arbitrary way
        Dialog dialog = super.onCreateDialog( savedInstanceState ); 
        DialogUtils.setMargins( dialog, 0, 150, 50, 75 );
        return dialog;
    }
    

    This is the method applying the margins to the dialog:

    public static Dialog setMargins( Dialog dialog, int marginLeft, int marginTop, int marginRight, int marginBottom )
    {
        Window window = dialog.getWindow();
        if ( window == null )
        {
            // dialog window is not available, cannot apply margins
            return dialog;
        }
        Context context = dialog.getContext();
    
        // set dialog to fullscreen
        RelativeLayout root = new RelativeLayout( context );
        root.setLayoutParams( new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT ) );
        dialog.requestWindowFeature( Window.FEATURE_NO_TITLE );
        dialog.setContentView( root );
        // set background to get rid of additional margins
        window.setBackgroundDrawable( new ColorDrawable( Color.WHITE ) );
    
        // apply left and top margin directly
        window.setGravity( Gravity.LEFT | Gravity.TOP );
        LayoutParams attributes = window.getAttributes();
        attributes.x = marginLeft;
        attributes.y = marginTop;
        window.setAttributes( attributes );
    
        // set right and bottom margin implicitly by calculating width and height of dialog
        Point displaySize = getDisplayDimensions( context );
        int width = displaySize.x - marginLeft - marginRight;
        int height = displaySize.y - marginTop - marginBottom;
        window.setLayout( width, height );
    
        return dialog;
    }
    

    Here are the helper methods I used:

    @NonNull
    public static Point getDisplayDimensions( Context context )
    {
        WindowManager wm = ( WindowManager ) context.getSystemService( Context.WINDOW_SERVICE );
        Display display = wm.getDefaultDisplay();
    
        DisplayMetrics metrics = new DisplayMetrics();
        display.getMetrics( metrics );
        int screenWidth = metrics.widthPixels;
        int screenHeight = metrics.heightPixels;
    
        // find out if status bar has already been subtracted from screenHeight
        display.getRealMetrics( metrics );
        int physicalHeight = metrics.heightPixels;
        int statusBarHeight = getStatusBarHeight( context );
        int navigationBarHeight = getNavigationBarHeight( context );
        int heightDelta = physicalHeight - screenHeight;
        if ( heightDelta == 0 || heightDelta == navigationBarHeight )
        {
            screenHeight -= statusBarHeight;
        }
    
        return new Point( screenWidth, screenHeight );
    }
    
    public static int getStatusBarHeight( Context context )
    {
        Resources resources = context.getResources();
        int resourceId = resources.getIdentifier( "status_bar_height", "dimen", "android" );
        return ( resourceId > 0 ) ? resources.getDimensionPixelSize( resourceId ) : 0;
    }
    
    public static int getNavigationBarHeight( Context context )
    {
        Resources resources = context.getResources();
        int resourceId = resources.getIdentifier( "navigation_bar_height", "dimen", "android" );
        return ( resourceId > 0 ) ? resources.getDimensionPixelSize( resourceId ) : 0;
    }
    

    The helper methods are explained in another of my SO answers.

    This Gist contains an extended versions that supports immersve mode too.

提交回复
热议问题