Search code examples
javaandroidandroid-alertdialog

Android AlertDialog align buttons to bottom not working


I have an Android AlertDialog with some info and Neutral and Positive buttons.

I set the size of the AlertDialog with the following line, which gives it the correct height that i want:

MaterialAlertDialogBuilder alert = new MaterialAlertDialogBuilder(context);
alert.setView(wifiResultView);
// stuff
alertDialog = alert.show();
alertDialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

However, the buttons align with the end of the data in the dialog and i can't for the life of me figure out how to get them to stick to the bottom. Does anybody have any idea? I would greatly appreciate it.

I want the buttons to stick to the bottom of the window, with space between the data and the buttons (not with space below the buttons like in the picture).

I'm using Android 11 (Samsung Galaxy S10e)

enter image description here

Thanks a bunch!


Solution

  • This is the default behaviour of AlertDialog. To align buttons to bottom you have to change also the height of AlertDialogLayout which is the alert container to MATCH_PARENT. Unfortunately there is no currently a public API to retrieve the AlertDialogLayout from AlertDialog, so below i will describe two possible solutions to retrieve it from AlertDialog and change its height.

    1.Find the AlertDialogLayout directly from the PositiveButton:

    Button btn = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
    AlertDialogLayout alertDialogLayout = (AlertDialogLayout) btn.getParent().getParent().getParent();
    alertDialogLayout.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
    

    2.Find the AlertDialogLayout in a recurring way starting from the PositiveButton root view:

    Button btn = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
    View rootView = btn.getRootView();
    findAlertDialogLayoutAndSetParams(rootView);
    

    where findAlertDialogLayoutAndSetParams(View view) is a helper function and it reccurres until it finds the AlertDialogLayout:

    private void findAlertDialogLayoutAndSetParams(View view){
    
        if(view instanceof ViewGroup) {
            ViewGroup viewGroup = (ViewGroup)view;
            for(int i = 0; i < viewGroup.getChildCount(); i++) {
                View childView = viewGroup.getChildAt(i);
                if(childView instanceof ViewGroup) {
                    if(childView instanceof AlertDialogLayout){
                        AlertDialogLayout alertDialogLayout = (AlertDialogLayout)childView;
                        alertDialogLayout.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
                    }
                    else {
                        findAlertDialogLayoutAndSetParams(childView);
                    }
                }
            }
        }
    }
    

    Complete Example:

    //get your custom view
    LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View wifiResultView = mInflater.inflate(R.layout.alert_view_layout, null, false);
    
    //create the MaterialAlertDialogBuilder
    MaterialAlertDialogBuilder alert = new MaterialAlertDialogBuilder(context);
    alert.setPositiveButton("Ok", null);
    alert.setNeutralButton("Cancel", null);
    alert.setView(wifiResultView);
    AlertDialog alertDialog = alert.show();
    alertDialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
    
    //stick the buttons to the bottom by setting the height of AlertDialogLayout to MATCH_PARENT
    //1st option - get the AlertDialogLayout directly from the positive button
    Button btn = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
    AlertDialogLayout alertDialogLayout = (AlertDialogLayout) btn.getParent().getParent().getParent();
    alertDialogLayout.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
    
    //2nd option - find AlertDialogLayout in a recurring way starting from the positive button root view
    //Button btn = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
    //View rootView = btn.getRootView();
    //findAlertDialogLayoutAndSetParams(rootView);
    

    Results before/after:

    buttons_before buttons_after