Полный экран DialogFragment в Android

Я пытаюсь показать почти полноэкранный DialogFragment. Но я как-то не в состоянии это сделать.

То, как я показываю фрагмент, прямо из документации разработчика Android.

FragmentManager f = ((Activity)getContext()).getFragmentManager();
FragmentTransaction ft = f.beginTransaction();
Fragment prev = f.findFragmentByTag("dialog");
if (prev != null) {
    ft.remove(prev);
}
ft.addToBackStack(null);

// Create and show the dialog.
DialogFragment newFragment = new DetailsDialogFragment();
newFragment.show(ft, "dialog");

Я наивно пытался установить RelativeLayout в фрагменте fill_parent, а некоторые minWidth и minHeight.

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"  
    android:minWidth="1000px" 
    android:minHeight="600px"
    android:background="#ff0000">

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

Я также попытался установить атрибуты Window в коде, как предлагается здесь: http://groups.google.com/group/android-developers/browse_thread/thread/f0bb813f643604ec. Но это тоже не помогло.

Я, вероятно, неправильно понимаю, как Android обрабатывает диалоговые окна, поскольку я новичок в этом. Как я могу сделать что-то подобное? Есть ли альтернативные способы достижения моей цели?


Android-устройство:
Asus EeePad Transformer
Android 3.0.1


Update: Теперь мне удалось получить его на полный экран, со следующим кодом в фрагменте

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setStyle(STYLE_NO_FRAME, android.R.style.Theme_Holo_Light);
}

К сожалению, это не совсем то, чего я хочу. Мне определенно нужно небольшое "дополнение" вокруг диалогового окна, чтобы показать фон.

Любые идеи, как это сделать?

Ответ 1

Попробуйте переключиться на LinearLayout вместо RelativeLayout. Я тестировал 3.0 Honeycomb api при тестировании.

public class FragmentDialog extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Button button = (Button) findViewById(R.id.show);
    button.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            showDialog();
        }
    });
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
}

void showDialog() {
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    DialogFragment newFragment = MyDialogFragment.newInstance();
    newFragment.show(ft, "dialog");
}

public static class MyDialogFragment extends DialogFragment {

    static MyDialogFragment newInstance() {
        MyDialogFragment f = new MyDialogFragment();
        return f;
    }

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

}
}

и макеты: fragment_dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<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"> 
 </LinearLayout> 

main.xml

<?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:background="#ffffff">
    <Button android:id="@+id/show"
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"
        android:layout_weight="0"
        android:text="show">
    </Button>
</LinearLayout>

Ответ 2

Чтобы получить DialogFragment во весь экран

Переопределите onStart вашего диалогового окна так:

@Override
public void onStart()
{
    super.onStart();
    Dialog dialog = getDialog();
    if (dialog != null)
    {
        int width = ViewGroup.LayoutParams.MATCH_PARENT;
        int height = ViewGroup.LayoutParams.MATCH_PARENT;
        dialog.getWindow().setLayout(width, height);
    }
}

И спасибо большое за это сообщение: The-mystery-of-androids-full-screen-dialog-fragments

Ответ 3

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

    setStyle(DialogFragment.STYLE_NORMAL,
             android.R.style.Theme_Black_NoTitleBar_Fullscreen);
}

Ответ 4

В соответствии с этой ссылкой полноэкранный диалог DialogFragment показывает пополнение по сторонам, это будет работать как шарм.

@Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {

    // the content
    final RelativeLayout root = new RelativeLayout(getActivity());
    root.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));

    // creating the fullscreen dialog
    final Dialog dialog = new Dialog(getActivity());
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    dialog.setContentView(root);
    dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
    dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

    return dialog;
}

Ответ 5

В моем случае я использовал следующий подход:

    @Override
    public void onStart() {
        super.onStart();
        getDialog().getWindow().setLayout(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
    }
}

Плюс LinearLayout, чтобы заполнить все пространство содержимым.

Но между левым и правым краями диалога и краями экрана на некоторых устройствах Lollipop + (например, Nexus 9) были еще небольшие пробелы.

Это не было очевидно, но, наконец, я понял, что для полной ширины для всех устройств и платформ фона фона должен быть указан внутри styles.xml, как показано ниже

<style name="Dialog.NoTitle" parent="Theme.AppCompat.Dialog">
    <item name="android:windowNoTitle">true</item>
    <item name="android:padding">0dp</item>
    <item name="android:windowBackground">@color/window_bg</item>
</style>

И, конечно, этот стиль нужно использовать, когда мы создаем диалог следующим образом:

    public static DialogFragment createNoTitleDlg() {
        DialogFragment frag = new Some_Dialog_Frag();
        frag.setStyle(DialogFragment.STYLE_NO_TITLE, R.style.Dialog_NoTitle);
        return frag;
}

Ответ 6

Сделайте полноэкранный DialogFragment, используя только стиль

Первое решение

1. Добавьте в свой style.xml :

    <style name="FullScreenDialog" parent="Theme.AppCompat.Light.Dialog">
        <item name="android:backgroundDimEnabled">false</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:padding">0dp</item>
        <item name="android:windowIsFloating">false</item>
        <item name="android:windowBackground">@android:color/transparent</item>
    </style>

2. Добавьте в свой DialogFragment:

@Override
public int getTheme() {
    return R.style.FullScreenDialog;
}

Альтернативное решение

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    setStyle(DialogFragment.STYLE_NO_FRAME, R.style.AppTheme)
}

где AppTheme - это тема, которую вы определили в стилях.

Ответ 7

Я столкнулся с проблемой перед использованием полноэкранного диалоговогофрагмента: всегда есть отступы при установке полноэкранного режима. попробуйте этот код в диалогеFragment onActivityCreated():

public void onActivityCreated(Bundle savedInstanceState)
{   
    super.onActivityCreated(savedInstanceState);
    Window window = getDialog().getWindow();
    LayoutParams attributes = window.getAttributes();
    //must setBackgroundDrawable(TRANSPARENT) in onActivityCreated()
    window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
    if (needFullScreen)
    {
        window.setLayout(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
    }
}

Ответ 8

Что касается обновления API Android, предлагаемый метод отображения полного диалогового окна выглядит следующим образом:

FragmentTransaction transaction = this.mFragmentManager.beginTransaction();
// For a little polish, specify a transition animation
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
// To make it fullscreen, use the 'content' root view as the container
// for the fragment, which is always the root view for the activity
transaction.add(android.R.id.content, this.mFragmentToShow).commit();

в противном случае, если вы не хотите, чтобы он отображался в полноэкранном режиме, вы можете сделать так:

this.mFragmentToShow.show(this.mFragmentManager, LOGTAG);

Надеюсь, что это поможет.

ИЗМЕНИТЬ

Помните, что решение, которое я дал, но имеет слабость, которая иногда может быть неприятной. Добавление DialogFragment в контейнер android.R.id.content не позволит вам правильно обрабатывать функцию DialogFragment#setCancelable() и может привести к неожиданному поведению при добавлении самого DialogFragment в задний стек.

Итак, я предложил вам просто изменить стиль вашего DialogFragment в методе onCreate следующим образом:

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Translucent_NoTitleBar);
}

Надеюсь, что это поможет.

Ответ 9

Попробуйте использовать setStyle() в onCreate и переопределить onCreateDialog сделать диалог без заголовка

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);    
    setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme);        
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    Dialog dialog = super.onCreateDialog(savedInstanceState);
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);        
    return dialog;
}

или просто переопределите onCreate() и setStyle со своим кодом.

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);    
    setStyle(DialogFragment.STYLE_NO_TITLE, android.R.style.Theme);        
}

Ответ 10

Это действительно зависит от того, как определяется макет. Но чтобы гарантировать, что диалог получит требуемый размер, лучшим решением будет предоставить LayoutParams после отображения диалога (а не создания). В диалоговом окне диалога диалог отображается в onStart, поэтому допустимый метод для получения полной ширины:

@Override public void onStart() {
    super.onStart();
    Dialog d = getDialog();
    if (d!=null){
        d.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
    }
}

Чтобы также указать тему или стиль, например стиль NO_TITLE, наилучшее расположение находится в методе onCreate:

@Override public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setStyle(STYLE_NO_TITLE, android.R.style.Theme_Holo_Light_Dialog);
}

Ответ 11

Вот решение, как я понял эту проблему:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    Dialog dialog = super.onCreateDialog(savedInstanceState);    
    dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);   

    return dialog;
}

@Override
public void onStart() {
    super.onStart();
    Dialog dialog = getDialog();
    if (dialog != null) {
            dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
            dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
    }
}

Ответ 12

Чираг Нагария прав, кроме добавления "_Fullscreen". его можно решить, используя любой базовый стиль, который не был получен из стиля Dialog. 'android.R.style.Theme_Black_NoTitleBar' также может использоваться.

Ответ 13

Создайте под темой в вашем стиле .xml:

<style name="DialogTheme" parent="Theme.AppCompat.Light.DarkActionBar">
   <item name="android:paddingRight">0dp</item>
   <item name="android:paddingLeft">0dp</item>
   <item name="android:layout_width">match_parent</item>
   <item name="android:windowNoTitle">true</item>
</style>

затем установите стиль в диалоговом окне "Диалог"

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NO_TITLE, R.style.DialogTheme);
}

Ответ 14

Примечание. Даже здесь можно найти правильный ответ. Но я хочу уточнить путаницу.

Используйте код ниже для android.app.DialogFragment

@Override
public void onStart()
{
    super.onStart();
    Dialog dialog = getDialog();
    if (dialog != null)
    {
        int width = ViewGroup.LayoutParams.MATCH_PARENT;
        int height = ViewGroup.LayoutParams.MATCH_PARENT;
        dialog.getWindow().setLayout(width, height);
    }
}

Используйте следующий код для android.support.v4.app.DialogFragment

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Black_NoTitleBar_Fullscreen);
}

Ответ 15

В случае, если кто-то еще сталкивается с этим, у меня был подобный опыт, но оказалось, что проблема заключалась в том, что я забыл вернуть завышенное представление из onCreateView (вместо этого вернул default super.onCreateView). Я просто вернул правильное завышенное представление и решил проблему.

Ответ 16

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    Dialog dialog = new Dialog(getActivity(), android.R.style.Theme_Holo_Light);
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);

    return dialog;
}

Это решение применяет полноэкранную тему в диалоговом окне, которая похожа на Chirag setStyle в onCreate. Недостатком является то, что savedInstanceState не используется.

Ответ 17

Попробуйте это для общего диалога фрагментов для нескольких применений. Надеюсь, это поможет вам сделать ставку

public class DialogFragment extends DialogFragment {

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

        getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        initializeUI(rootView);
        return rootView;
    }

    @Override
    public void onStart() {
        super.onStart();
        Dialog dialog = getDialog();
        if (dialog != null) {
            int width = ViewGroup.LayoutParams.MATCH_PARENT;
            int height = ViewGroup.LayoutParams.MATCH_PARENT;
            dialog.getWindow().setLayout(width, height);
        }
    }
    private void initializeUI(View rootView) {
    //getChildFragmentManager().beginTransaction().replace(R.id.fv_container,FragmentVisitHistory.getInstance(), AppConstant.FRAGMENT_VISIT_HISTORY).commit();
    }
}

Ответ 18

Это то, что вам нужно установить для фрагмента:

/* theme is optional, I am using leanback... */
setStyle(STYLE_NORMAL, R.style.AppTheme_Leanback);

В вашем случае:

DialogFragment newFragment = new DetailsDialogFragment();
newFragment.setStyle(STYLE_NORMAL, R.style.AppTheme_Leanback);
newFragment.show(ft, "dialog");

И почему? Поскольку DialogFragment (если не указано явно), будет использовать его внутренние стили, которые будут вставлять в него свой собственный макет (без полноэкранного просмотра и т.д.).

И макет? Нет необходимости в хакерском режиме, это работает отлично:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    ...
</RelativeLayout>

Enjoy

Ответ 19

Я очень поздно отвечаю на этот вопрос, но хочу поделиться этим ответом, чтобы в будущем кто-то мог это использовать.

Я использовал этот код в своем проекте, он работает как в более низкой версии, так и в более высокой версии.

Просто используйте эту тему внутри onCreateDialog() следующим образом:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {

    View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_pump_details, null);

    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), android.R.style.Theme_Black_NoTitleBar_Fullscreen);
    return builder.create();
}

android.R.style.Theme_Black_NoTitleBar_Fullscreen - вот исходный код этой темы, вы можете видеть, что только эта тема достаточно, чтобы сделать DialogFragment отображаемым в полноэкранном режиме.

<!-- Variant of {@link #Theme_Black} that has no title bar and
     no status bar.  This theme
     sets {@link android.R.attr#windowFullscreen} to true.  -->
<style name="Theme.Black.NoTitleBar.Fullscreen">
    <item name="windowFullscreen">true</item>
    <item name="windowContentOverlay">@null</item>
</style>

Пожалуйста, дайте мне знать, если кто-нибудь столкнется с какой-либо проблемой. Надеюсь, это полезно. Спасибо:)

Ответ 20

Следующий способ будет работать, даже если вы работаете с относительной компоновкой. Выполните следующие действия:

  • Перейти к редактору тем (доступно в разделе Инструменты- > Android → Редактор тем)
  • Выберите все темы. Выберите тот, у кого AppCompat.Dialog
  • Выберите опцию фона окна Android, если вы хотите, чтобы он имел какой-либо цветной фон или прозрачный.
  • Выберите цвет и нажмите OK. Выберите имя новой темы.
  • Перейдите в styles.xml, а затем под только что добавленной темой, добавьте эти два атрибута:

    <item name="android:windowNoTitle">true</item>
    <item name="android:windowIsFloating">false</item>
    

Настройки моей темы для диалога:

<style name="DialogTheme" parent="Theme.AppCompat.Dialog" >
    <item name="android:layout_width">match_parent</item>
    <item name="android:layout_height">match_parent</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowIsFloating">false</item>

Убедитесь, что тема имеет родителя как Theme.AppCompat.Dialog Другой способ - просто создать новый стиль в styles.xml и изменить его в соответствии с приведенным выше кодом.

  1. Перейдите к классу фрагмента диалога и в методе onCreate(), установите стиль вашего диалога как:

    @Override public void onCreate (@Nullable Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   SetStyle (DialogFragment.STYLE_NORMAL, R.style.DialogTheme); }

Ответ 21

И версия котлин!

override fun onStart() {
    super.onStart()
    dialog?.let {
        val width = ViewGroup.LayoutParams.MATCH_PARENT
        val height = ViewGroup.LayoutParams.MATCH_PARENT
        it.window?.setLayout(width, height)
    }
}

Ответ 22

window.setLayout недостаточно для старых устройств.

Вот что я делаю:

try {
    ViewGroup parent = (ViewGroup) view;
    do {
        parent = (ViewGroup) parent.getParent();
        if (parent == null)
            break;

        parent.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
        parent.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
        parent.requestLayout();
    } while (true);
} catch (Exception e){}

Ответ 23

This below answer works for me in fragment dialog.  


  Dialog dialog = getDialog();
        if (dialog != null)
        {
            int width = ViewGroup.LayoutParams.MATCH_PARENT;
            int height = ViewGroup.LayoutParams.MATCH_PARENT;
            dialog.getWindow().setLayout(width, height);
        }

Ответ 24

Добавьте следующие строки в стиле полноэкранного диалога.

<item name="android:windowNoTitle">true</item>
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowIsFloating">false</item>

Ответ 25

Решение с использованием нового ConstraintLayout заключается в обертывании ConstraintLayout в LinearLayout с фиксированными minHeight и minWidth. Без упаковки ConstraintLayout не получает правильный размер для диалога.

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

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/background_color"
        android:orientation="vertical">
        <!-- some constrained views -->
    </androidx.constraintlayout.widget.ConstraintLayout>

</LinearLayout>