How to make an alert dialog fill 90% of screen siz

2019-01-01 10:29发布

问题:

I can create and display a custom alert dialog just fine but even so I have android:layout_width/height=\"fill_parent\" in the dialog xml it is only as big as the contents.

What I want is dialog that fills the entire screen except maybe a padding of 20 pixel. Then the image that is part of the dialog would automatically stretch to the full dialog size with fill_parent.

回答1:

According to Android platform developer Dianne Hackborn in this discussion group post, Dialogs set their Window\'s top level layout width and height to WRAP_CONTENT. To make the Dialog bigger, you can set those parameters to MATCH_PARENT.

Demo code:

    AlertDialog.Builder adb = new AlertDialog.Builder(this);
    Dialog d = adb.setView(new View(this)).create();
    // (That new View is just there to have something inside the dialog that can grow big enough to cover the whole screen.)

    WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
    lp.copyFrom(d.getWindow().getAttributes());
    lp.width = WindowManager.LayoutParams.MATCH_PARENT;
    lp.height = WindowManager.LayoutParams.MATCH_PARENT;
    d.show();
    d.getWindow().setAttributes(lp);

Note that the attributes are set after the Dialog is shown. The system is finicky about when they are set. (I guess that the layout engine must set them the first time the dialog is shown, or something.)

It would be better to do this by extending Theme.Dialog, then you wouldn\'t have to play a guessing game about when to call setAttributes. (Although it\'s a bit more work to have the dialog automatically adopt an appropriate light or dark theme, or the Honeycomb Holo theme. That can be done according to http://developer.android.com/guide/topics/ui/themes.html#SelectATheme )



回答2:

Try wrapping your custom dialog layout into RelativeLayout instead of LinearLayout. That worked for me.



回答3:

Specifying FILL_PARENT on the dialog window, like others suggested, did not work for me (on Android 4.0.4), because it just stretched the black dialog background to fill the whole screen.

What works fine is using the minimum display value, but specifying it within the code, so that the dialog takes 90% of the screen.

So:

Activity activity = ...;
AlertDialog dialog = ...;

// retrieve display dimensions
Rect displayRectangle = new Rect();
Window window = activity.getWindow();
window.getDecorView().getWindowVisibleDisplayFrame(displayRectangle);

// inflate and adjust layout
LayoutInflater inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.your_dialog_layout, null);
layout.setMinimumWidth((int)(displayRectangle.width() * 0.9f));
layout.setMinimumHeight((int)(displayRectangle.height() * 0.9f));

dialog.setView(layout);

In general only adjusting the width should be sufficient in most cases.



回答4:

Set android:minWidth and android:minHeight in your custom view xml. These can force the alert not to just wrap content size. Using a view like this should do it:

<LinearLayout
  xmlns:android=\"http://schemas.android.com/apk/res/android\"
  android:layout_width=\"fill_parent\"
  android:layout_height=\"fill_parent\"
  android:minWidth=\"300dp\" 
  android:minHeight=\"400dp\">
  <ImageView
   android:layout_width=\"fill_parent\"
   android:layout_height=\"fill_parent\"
   android:background=\"@drawable/icon\"/>
</LinearLayout>


回答5:

dialog.getWindow().setLayout(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);


回答6:

Even simpler just do this:

int width = (int)(getResources().getDisplayMetrics().widthPixels*0.90);
int height = (int)(getResources().getDisplayMetrics().heightPixels*0.90);

alertDialog.getWindow().setLayout(width, height);


回答7:

All of the other answers here makes sense, but it did not meet what Fabian needs. Here is a solution of mine. It may not be the perfect solution but it works for me. It shows a dialog which is on fullscreen but you can specify a padding on top, bottom, left or right.

First put this in your res/values/styles.xml :

<style name=\"CustomDialog\" parent=\"@android:style/Theme.Dialog\">
    <item name=\"android:windowIsTranslucent\">true</item>
    <item name=\"android:windowBackground\">@color/Black0Percent</item>
    <item name=\"android:paddingTop\">20dp</item>
    <item name=\"android:windowContentOverlay\">@null</item>
    <item name=\"android:windowNoTitle\">true</item>
    <item name=\"android:backgroundDimEnabled\">false</item>
    <item name=\"android:windowIsFloating\">false</item>
</style>

As you can see I have there android:paddingTop= 20dp is basically what you need. The android:windowBackground = @color/Black0Percent is just a color code declared on my color.xml

res/values/color.xml

<?xml version=\"1.0\" encoding=\"utf-8\"?>
<resources>
<color name=\"Black0Percent\">#00000000</color>
</resources>

That Color code just serves as a dummy to replace the default window background of the Dialog with a 0% transparency color.

Next build the custom dialog layout res/layout/dialog.xml

<?xml version=\"1.0\" encoding=\"utf-8\"?>
<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"
    android:id=\"@+id/dialoglayout\"
    android:layout_width=\"match_parent\"
    android:background=\"@drawable/DesiredImageBackground\"
    android:layout_height=\"match_parent\"
    android:orientation=\"vertical\" >

    <EditText
        android:id=\"@+id/edittext1\"
        android:layout_width=\"match_parent\"
        android:layout_height=\"wrap_content\"
        android:singleLine=\"true\"
        android:textSize=\"18dp\" />

    <Button
        android:id=\"@+id/button1\"
        android:layout_width=\"match_parent\"
        android:layout_height=\"wrap_content\"
        android:text=\"Dummy Button\"
        android:textSize=\"18dp\" />

</LinearLayout>

Finally here is our dialog that set custom view which uses our dialog.xml:

Dialog customDialog;
LayoutInflater inflater = (LayoutInflater) getLayoutInflater();
View customView = inflater.inflate(R.layout.dialog, null);
// Build the dialog
customDialog = new Dialog(this, R.style.CustomDialog);
customDialog.setContentView(customView);
customDialog.show();

Conclusion: I tried to override the dialog\'s theme in the styles.xml named CustomDialog. It overrides the Dialog window layout and gives me the chance to set a padding and change the opacity of the background. It may not be the perfect solution but I hope it helps you..:)



回答8:

You can use percentage for (JUST) windows dialog width.

Look into this example from Holo Theme:

<style name=\"Theme.Holo.Dialog.NoActionBar.MinWidth\">
    <item name=\"android:windowMinWidthMajor\">@android:dimen/dialog_min_width_major</item>
    <item name=\"android:windowMinWidthMinor\">@android:dimen/dialog_min_width_minor</item>
</style>

 <!-- The platform\'s desired minimum size for a dialog\'s width when it
     is along the major axis (that is the screen is landscape).  This may
     be either a fraction or a dimension. -->
<item type=\"dimen\" name=\"dialog_min_width_major\">65%</item>

All you need to do is extend this theme and change the values for \"Major\" and \"Minor\" to 90% instead 65%.

Regards.



回答9:

The following worked fine for me:

    <style name=\"MyAlertDialogTheme\" parent=\"Base.Theme.AppCompat.Light.Dialog.Alert\">
        <item name=\"windowFixedWidthMajor\">90%</item>
        <item name=\"windowFixedWidthMinor\">90%</item>
    </style>

(note: windowMinWidthMajor/Minor as suggested in previous answers didn\'t do the trick. My dialogs kept changing sizes depending on the content)

and then:

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.MyAlertDialogTheme);


回答10:

Solution with actual 90% calculation:

@Override public void onStart() {
   Dialog dialog = getDialog();
   if (dialog != null) {
     dialog.getWindow()
        .setLayout((int) (getScreenWidth(getActivity()) * .9), ViewGroup.LayoutParams.MATCH_PARENT);
   }
}

where getScreenWidth(Activity activity) is defined the following (best put in a Utils class):

public static int getScreenWidth(Activity activity) {
   Point size = new Point();
   activity.getWindowManager().getDefaultDisplay().getSize(size);
   return size.x;
}


回答11:

Well, you have to set your dialog\'s height and width before to show this ( dialog.show() )

so, do something like this:

dialog.getWindow().setLayout(width, height);

//then

dialog.show()


回答12:

By far the most simplest way I can think of -

If your dialog is made out of a vertical LinearLayout, just add a \"height filling\" dummy view, that will occupy the entire height of the screen.

For example -

<?xml version=\"1.0\" encoding=\"utf-8\"?>
<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"
          android:orientation=\"vertical\"
          android:layout_width=\"match_parent\"
          android:layout_height=\"match_parent\"
          android:weightSum=\"1\">

    <EditText
       android:layout_width=\"match_parent\"
       android:layout_height=\"wrap_content\"
       android:id=\"@+id/editSearch\" />

    <ListView
       android:layout_width=\"match_parent\"
       android:layout_height=\"match_parent\"
       android:id=\"@+id/listView\"/>


   <!-- this is a dummy view that will make sure the dialog is highest -->
   <View
       android:layout_width=\"match_parent\"
       android:layout_height=\"match_parent\"
       android:layout_weight=\"1\"/>

</LinearLayout>

Notice the android:weightSum=\"1\" in the LinearLayout\'s attributes and the android:layout_weight=\"1\" in the dummy View\'s attributes



回答13:

Well, you have to set your dialog\'s height and width before to show this ( dialog.show() )

so, do something like this:

dialog.getWindow().setLayout(width, height);

//then

dialog.show()

Getting this code, i made it some changes:

dialog.getWindow().setLayout((int)(MapGeaGtaxiActivity.this.getWindow().peekDecorView().getWidth()*0.9),(int) (MapGeaGtaxiActivity.this.getWindow().peekDecorView().getHeight()*0.9));

however, dialog size\'s could change when the device change its position. Perhaps you need to handle by your own when metrics changes. PD: peekDecorView, implies that layout in activity is properly initialized otherwise you may use

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int wwidth = metrics.widthPixels;

in order to get screen size



回答14:

After initialize your dialog object and set the content view. Do this and enjoy.

(in the case i am setting 90% to width and 70% to height because width 90% it will be over toolbar )

DisplayMetrics displaymetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int width = (int) ((int)displaymetrics.widthPixels * 0.9);
int height = (int) ((int)displaymetrics.heightPixels * 0.7);
d.getWindow().setLayout(width,height);
d.show();


回答15:

My answer is based on the koma\'s but it doesn\'t require to override onStart but only onCreateView which is almost always overridden by default when you create new fragments.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.your_fragment_layout, container);

    Rect displayRectangle = new Rect();
    Window window = getDialog().getWindow();
    window.getDecorView().getWindowVisibleDisplayFrame(displayRectangle);

    v.setMinimumWidth((int)(displayRectangle.width() * 0.9f));
    v.setMinimumHeight((int)(displayRectangle.height() * 0.9f));

    return v;
}

I\'ve tested it on Android 5.0.1.



回答16:

Get the device width:

public static int getWidth(Context context) {
    DisplayMetrics displayMetrics = new DisplayMetrics();
    WindowManager windowmanager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    windowmanager.getDefaultDisplay().getMetrics(displayMetrics);
    return displayMetrics.widthPixels;
}

then use that for making dialog 90% of device,

Dialog filterDialog = new Dialog(context, R.style.searchsdk_FilterDialog);

filterDialog.setContentView(R.layout.searchsdk_filter_popup);
initFilterDialog(filterDialog);
filterDialog.setCancelable(true);
filterDialog.getWindow().setLayout(((getWidth(context) / 100) * 90), LinearLayout.LayoutParams.MATCH_PARENT);
filterDialog.getWindow().setGravity(Gravity.END);
filterDialog.show();


回答17:

Here is my variant for custom dialog\'s width:

DisplayMetrics displaymetrics = new DisplayMetrics();
mActivity.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int width = (int) (displaymetrics.widthPixels * (ThemeHelper.isPortrait(mContext) ? 0.95 : 0.65));

WindowManager.LayoutParams params = getWindow().getAttributes();
params.width = width;
getWindow().setAttributes(params);

So depending on device orientation (ThemeHelper.isPortrait(mContext)) dialog\'s width will be either 95% (for portrait mode) or 65% (for landscape). It\'s a little more that the author asked but it could be useful to someone.

You need to create a class that extends from Dialog and put this code into your onCreate(Bundle savedInstanceState) method.

For dialog\'s height the code should be similar to this.



回答18:

public static WindowManager.LayoutParams setDialogLayoutParams(Activity activity, Dialog dialog)
    {
        try 
        {
            Display display = activity.getWindowManager().getDefaultDisplay();
            Point screenSize = new Point();
            display.getSize(screenSize);
            int width = screenSize.x;

            WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
            layoutParams.copyFrom(dialog.getWindow().getAttributes());
            layoutParams.width = (int) (width - (width * 0.07) ); 
            layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
            return layoutParams;
        } 
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }


回答19:

Above many of the answers are good but none of the worked for me fully. So i combined the answer from @nmr and got this one.

final Dialog d = new Dialog(getActivity());
        //  d.getWindow().setBackgroundDrawable(R.color.action_bar_bg);
        d.requestWindowFeature(Window.FEATURE_NO_TITLE);
        d.setContentView(R.layout.dialog_box_shipment_detail);

        WindowManager wm = (WindowManager) getActivity().getSystemService(Context.WINDOW_SERVICE); // for activity use context instead of getActivity()
        Display display = wm.getDefaultDisplay(); // getting the screen size of device
        Point size = new Point();
        display.getSize(size);
        int width = size.x - 20;  // Set your heights
        int height = size.y - 80; // set your widths

        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
        lp.copyFrom(d.getWindow().getAttributes());

        lp.width = width;
        lp.height = height;

        d.getWindow().setAttributes(lp);
        d.show();


回答20:

    ...
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    Dialog d = builder.create(); //create Dialog
    d.show(); //first show

    DisplayMetrics metrics = new DisplayMetrics(); //get metrics of screen
    getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
    int height = (int) (metrics.heightPixels*0.9); //set height to 90% of total
    int width = (int) (metrics.widthPixels*0.9); //set width to 90% of total

    d.getWindow().setLayout(width, height); //set layout


回答21:

Here is a short answer that worked for me (Tested on API 8 and API 19).

Dialog mDialog;
View   mDialogView;
...
// Get height
int height = mDialog.getWindow()
.getWindowManager().getDefaultDisplay()
.getHeight();

// Set your desired padding (here 90%)
int padding = height - (int)(height*0.9f);

// Apply it to the Dialog
mDialogView.setPadding(
// padding left
0,
// padding top (90%)
padding, 
// padding right
0, 
// padding bottom (90%)
padding);


回答22:

you need to use a style @style.xml such as CustomDialog to displaying the customize-able dialog.

<style name=\"CustomDialog\" parent=\"@android:style/Theme.DeviceDefault.Light.Dialog\">
        <item name=\"android:windowIsTranslucent\">true</item>
        <item name=\"android:windowBackground\">@color/colorWhite</item>
        <item name=\"android:editTextColor\">@color/colorBlack</item>
        <item name=\"android:windowContentOverlay\">@null</item>
        <item name=\"android:windowNoTitle\">true</item>
        <item name=\"android:backgroundDimEnabled\">true</item>
        <item name=\"android:windowIsFloating\">true</item>
        <item name=\"android:windowSoftInputMode\">stateUnspecified|adjustPan</item>
    </style>

and use this style in Activity.java like this

Dialog dialog= new Dialog(Activity.this, R.style.CustomDialog);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(R.layout.custom_dialog);

and your custom_dialog.xml should inside your layout directory

<?xml version=\"1.0\" encoding=\"utf-8\"?>
<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"
    android:orientation=\"vertical\"
    android:layout_width=\"match_parent\"
    android:layout_height=\"match_parent\"
    android:paddingLeft=\"10dp\"
    android:paddingRight=\"10dp\">

    <TextView
        android:layout_width=\"match_parent\"
        android:layout_height=\"wrap_content\"
        android:text=\"\"
        android:textSize=\"20dp\"
        android:id=\"@+id/tittle_text_view\"
        android:textColor=\"@color/colorBlack\"
        android:layout_marginTop=\"20dp\"
        android:layout_marginLeft=\"10dp\"/>

    <LinearLayout
        android:layout_width=\"match_parent\"
        android:layout_height=\"wrap_content\"
        android:orientation=\"horizontal\"
        android:layout_marginLeft=\"20dp\"
        android:layout_marginBottom=\"10dp\"
        android:layout_marginTop=\"20dp\"
        android:layout_marginRight=\"20dp\">

        <EditText
            android:id=\"@+id/edit_text_first\"
            android:layout_width=\"50dp\"
            android:layout_height=\"match_parent\"
            android:hint=\"0\"
            android:inputType=\"number\" />

        <TextView
            android:id=\"@+id/text_view_first\"
            android:layout_width=\"wrap_content\"
            android:layout_height=\"match_parent\"
            android:layout_marginLeft=\"5dp\"
            android:gravity=\"center\"/>

        <EditText
            android:id=\"@+id/edit_text_second\"
            android:layout_width=\"50dp\"
            android:layout_height=\"match_parent\"
            android:hint=\"0\"
            android:layout_marginLeft=\"5dp\"
            android:inputType=\"number\" />

        <TextView
            android:id=\"@+id/text_view_second\"
            android:layout_width=\"wrap_content\"
            android:layout_height=\"match_parent\"
            android:layout_marginLeft=\"5dp\"
            android:gravity=\"center\"/>

    </LinearLayout>

</LinearLayout>


回答23:

dialog.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT,WindowManager.LayoutParams.WRAP_CONTENT);


回答24:

    final AlertDialog alertDialog;

    LayoutInflater li = LayoutInflater.from(mActivity);
    final View promptsView = li.inflate(R.layout.layout_dialog_select_time, null);

    RecyclerView recyclerViewTime;
    RippleButton buttonDone;

    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(mActivity);
    alertDialogBuilder.setView(promptsView);

    // create alert dialog
    alertDialog = alertDialogBuilder.create();

    /**
     * setting up window design
     */
    alertDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);


    alertDialog.show();

    DisplayMetrics metrics = new DisplayMetrics(); //get metrics of screen
    mActivity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
    int height = (int) (metrics.heightPixels * 0.9); //set height to 90% of total
    int width = (int) (metrics.widthPixels * 0.9); //set width to 90% of total

    alertDialog.getWindow().setLayout(width, height); //set layout
    recyclerViewTime = promptsView.findViewById(R.id.recyclerViewTime);


    DialogSelectTimeAdapter dialogSelectTimeAdapter = new DialogSelectTimeAdapter(this);
    RecyclerView.LayoutManager linearLayoutManager = new LinearLayoutManager(this);
    recyclerViewTime.setLayoutManager(linearLayoutManager);
    recyclerViewTime.setAdapter(dialogSelectTimeAdapter);

    buttonDone = promptsView.findViewById(R.id.buttonDone);
    buttonDone.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            alertDialog.dismiss();

        }
    });