Как я могу заставить окно активности в стиле диалога заполнить весь экран?


143

Я использую действие с установленной темой диалога и хочу, чтобы оно было полноэкранным. Я пробовал все, даже через WindowManager, чтобы вручную развернуть окно до полной ширины и высоты, но ничего не работает.

Очевидно, диалоговое окно (или действие с темой диалога) будет расширяться только в соответствии с его содержимым, но даже это не всегда работает. Например, я показываю кружок индикатора выполнения, ширина и высота которого установлены на FILL_PARENT (как и его контейнер макета), но все же диалоговое окно обтекает гораздо меньший индикатор выполнения, а не заполняет экран.

Должен быть способ отобразить что-то маленькое внутри диалогового окна, но должно ли оно расширяться до полного размера экрана без изменения размера его содержимого?


2
Интересное примечание: при установке фактического значения ширины и высоты контейнера макета в пикселях размер диалогового окна изменяется соответственно. Но если установить его на FILL_PARENT, тогда это не так ...
Маттиас,

В самом деле? Макет, который создает действие, имеет ли он родительский тег Relative или LinearLayout, для которого заданы высота и ширина fill_parent? Я реализовал несколько действий с темой диалога, и у меня никогда не было проблем с тем, чтобы она занимала весь экран.
MattC 02

Да, для действия LinearLayout задано значение FILL_PARENT как для ширины, так и для высоты.
Матиас,

Я вроде как решил проблему, используя обходной путь, но, поскольку это не очень хорошее решение, я оставлю вопрос открытым. Я создал подкласс LinearLayout и переопределил его метод onMeasure (), который отвечает за определение размера представления во время цикла компоновки, и зафиксировал его по ширине и высоте экрана. Однако это неверно, поскольку при этом не учитывается пространство, занимаемое строками меню, поэтому контейнер на самом деле будет выше, чем кажется на экране (со всеми странными побочными эффектами, такими как исчезновение детей в невидимых областях экрана). экран).
Матиас,

Я нашел правильное решение, см. Мой ответ ниже.
Матиас,

Ответы:


316

Я нашел решение:

В своей деятельности, для которой Theme.Dialogзадан стиль, сделайте следующее:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.your_layout);

    getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
}

Важно, чтобы вы звонили Window.setLayout() после звонка setContentView(), иначе ничего не получится.


5
Спасибо, сэкономили время, нигде я бы в этом не разобрался! но есть идеи, почему мы должны явно указывать в коде, почему fill_parent не работает через xml для действий с диалогом темы?
сб

3
Мой диалог не будет заполнять ширину ни по XML, ни по этому методу. Я ем ногти.
eitama

6
И это:import android.view.ViewGroup.LayoutParams;

11
FILL_PARENT теперь устарел, используйте вместо него
MATCH_PARENT

4
Он не заполняет весь экран, как будто у него есть небольшие отступы с каждой стороны.
Machado

66

Вы можете добавить эти значения в свой стиль android: windowMinWidthMajor и android: windowMinWidthMinor.

<style name="Theme_Dialog" parent="android:Theme.Holo.Dialog">
    ...
    <item name="android:windowMinWidthMajor">97%</item>
    <item name="android:windowMinWidthMinor">97%</item>
</style>

2
самое простое решение. Он также работает с библиотекой поддержки appcompat. Спасибо.
Мухаммад Сакиб

Это должен быть принятый ответ. Самый правильный и чистый способ сделать это. Рассмотрите возможность использования parent = "@ style / Theme.AppCompat.Light.Dialog"
Кирилл Кармазин

Кажется, это должно сработать, но для меня это не так. Хм, интересно, почему. Возможно, с 2014 года все изменилось.
SMBiggs

53

Я просто хочу заполнить только 80% экрана для этого, как это показано ниже

        DisplayMetrics metrics = getResources().getDisplayMetrics();
        int screenWidth = (int) (metrics.widthPixels * 0.80);

        setContentView(R.layout.mylayout);

        getWindow().setLayout(screenWidth, LayoutParams.WRAP_CONTENT); //set below the setContentview

он работает только тогда, когда я помещаю строку getwindow (). setLayout ... ниже setContentView (..)

спасибо @Matthias


12

Оберните свой dialog_custom_layout.xml в RelativeLayout вместо любого другого макета. У меня это сработало.


1
То же самое и здесь, ширина и высота были совершенно неправильными и не могли понять, как исправить. Преобразование корневого макета в RelativeLayout также устранило мои проблемы!
SharpMobileCode

8

Для диалога Это может быть полезно для кого-то. Я хочу, чтобы диалоговое окно занимало всю ширину экрана. много искал, но ничего полезного не нашел. Наконец, это сработало для меня:

mDialog.setContentView(R.layout.my_custom_dialog);
mDialog.getWindow().setBackgroundDrawable(null);

после добавления мой диалог появляется во всю ширину экрана.


5

Этот ответ - обходной путь для тех, кто использует Theme.AppCompat.Dialog или любые другие потомки Theme.AppCompat.Dialog, такие как Theme.AppCompat.Light.Dialog, Theme.AppCompat.DayNight.Dialog и т. Д. Я сам должен использовать диалоговое окно AppCompat, потому что я использую AppCompatActivity как расширение для всех моих действий. Если мы воспользуемся принятым ответом, возникнет проблема, из-за которой диалог будет иметь отступы со всех сторон (сверху, справа, снизу и слева).

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.your_layout);

    getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
}

В стиле вашей деятельности добавьте этот код

<style name="DialogActivityTheme" parent="Theme.AppCompat.Dialog">
    <item name="windowNoTitle">true</item>
    <item name="android:windowBackground">@null</item>
</style>

Как вы могли заметить, проблема, которая создает заполнение в нашем диалоговом окне, - это "android: windowBackground", поэтому здесь я устанавливаю фон окна равным нулю.


2

Установите минимальную ширину в самом верхнем макете.

android:minWidth="300dp"

Например:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"
  xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="300dp">

<!-- Put remaining contents here -->

</LinearLayout>

2

Ответ Матиаса в основном правильный, но он по-прежнему не заполняет весь экран, так как с каждой стороны есть небольшие отступы (на что указывает @Holmes). В дополнение к его коду мы могли бы исправить это, расширив стиль Theme.Dialog и добавив такие атрибуты.

<style name="MyDialog" parent="@android:style/Theme.Dialog">
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowNoTitle">true</item>
</style>

Затем мы просто объявляем Activity с установленной темой MyDialog:

<activity
    android:name=".FooActivity"
    android:theme="@style/MyDialog" />

1

Это было бы полезно для кого-то вроде меня. Создать собственный стиль диалога:

<style name="MyDialog" parent="Theme.AppCompat.Light.Dialog">
    <item name="windowNoTitle">true</item>
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowIsFloating">false</item>
</style>

В AndroidManifest.xmlфайле набора темы для желаемого действия:

<activity
        android:name=".CustomDialog"
        ...
        android:theme="@style/MyDialog"/>

На этом все, программно вызывать методы не нужно.


по-прежнему отображаются отступы с каждой стороны (сверху, справа, снизу и слева), и если нам нужно также показать строку состояния, это решение не
сработает

Проверьте stackoverflow.com/a/39590004/3940133, есть ли у вас отступы с каждой стороны
HendraWD 06

0

В вашем файле манифеста, где определена наша деятельность

<activity
        android:name=".YourPopUpActivity"
        android:theme="@android:style/Theme.Holo.Dialog" >
    </activity>

без панели действий

<activity android:name=".YourPopUpActivity"
            android:theme="@android:style/Theme.Holo.Dialog.NoActionBar"/>
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.