Custom Dialog size to match Theme.Holo.Light.Dialo

2019-02-02 15:19发布

问题:

If I have an Activity that has it's theme set to Theme.Holo.Light.Dialog, it will scale great. It will fill the screen on phones in portrait mode almost entirely but in landscape mode it won't stretch unreasonably long. For example, in this picture from Google, you can see the dialog not filling the whole screen.

It won't either collapse to match the width of the title like what will happen if you have your own Dialog build by having a class that extends the Dialog class.

This is what will happen with my layout.

What properties do I need to apply to the LinearLayout to make it scale pretty?

回答1:

You can use Theme.Holo.Light.Dialog.MinWidth for sizing your layout properly.

From the documentation:

public static final int Theme_Holo_Light_Dialog_MinWidth

Variant of Theme.Holo.Light.Dialog that has a nice minimum width for a regular dialog.

The way to use this would be through passing a ContextThemeWrapper in place of Context (using this) to your custom Dialog's constructor:

YourCustomDialog cDialog = new YourCustomDialog(
                        new ContextThemeWrapper(this, 
                              android.R.style.Theme_Holo_Light_Dialog_MinWidth));

This is how Theme.Holo.Light.Dialog.MinWidth is defined:

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

From dimens.xml:

@android:dimen/dialog_min_width_major:

<!-- 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>

@android:dimen/dialog_min_width_minor:

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

As it seems, the dialog's width in the picture you posted is around 65%. In the portrait mode, it would be 95%.

Honestly, the width doesn't look like 95 % in portrait mode, but it's better than before :):



回答2:

Just add two values to your custom theme.

<item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
<item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>

E.g.

<style name="MyDialog" parent="ThDialogBase">
        <item name="android:windowFrame">@null</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowBackground">@color/transparent</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
        <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
</style>


回答3:

In my custom dialog I use following properties and set dialog width to match parent and it's width scale properly.

 <item name="android:windowBackground">@null</item>
 <item name="android:windowIsFloating">false</item>


回答4:

Can you try to change your Dialog dimension at runtime, like this:

DisplayMetrics metrics = getResources().getDisplayMetrics();
int width = metrics.widthPixels;
yourDialog.show();
yourDialog.getWindow().setLayout((6 * width)/7, LayoutParams.WRAP_CONTENT);

or

Dialog yourDialog = dialogFragment.getDialog();
yourDialog.getWindow().setLayout((6 * width)/7, (4 * height)/5);

if you use Fragments.



回答5:

Two Scenarios

a. If you need it to fill the screen completely set your parents minWidth and minHeight to 1000dp

LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:minWidth="1000dp"  
    android:minHeight="1000dp"

b. If you need it to scale without filling the whole screen. Set one of the children of your LinearLayout within a RelativeLayout and set the relative layouts width to match_parent.