Полноэкранный 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 заполнит большую часть экрана. Но я только, кажется, изменить размер по вертикали, но только до некоторой фиксированной ширины по горизонтали.

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

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


Android Устройство:
Asus Eeepad Transformer
Android 3.0.1


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

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

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

есть идеи, как это сделать?

21 120

21 ответ:

попробуйте переключиться на 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> 

главная.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>

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

переопределить onStart вашего 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);
    }
}

и большое спасибо этому посту:the-mystery-of-androids-full-screen-dialog-fragments

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

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

}

по этой ссылке 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;
}

Я встретил эту проблему раньше при использовании полноэкранного dialogFragment: всегда есть заполнение при установке полноэкранного режима. попробуйте этот код в методе onactivitycreated () dialogFragment:

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);
    }
}

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

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

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

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

Это было не очевидно, но, наконец, я понял, что сделать это полная ширина на всех устройствах и платформах окне фон должно быть указано внутри стили.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;
}

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

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);

надеюсь, что это помогает.

EDIT

имейте в виду, что решение, которое я дал, работает, но имеет слабость, которая иногда может быть неприятной. Добавление 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);
}

надеюсь, что это помогает.

попробуйте использовать 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 fellow код.

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

сделать полноэкранный 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 это тема, которую вы определили в стилях.

это действительно может зависеть от того, как определяется макет. Но чтобы убедиться, что диалоговое окно получает необходимый размер, лучшим решением является предоставление LayoutParams после отображения диалогового окна (а не при создании). На DialogFragment диалог отображается на 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);
}

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

@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));

        }
    }

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

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

@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;
}

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

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

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();
    }
}

Это то, что вам нужно, чтобы установить фрагмент:

/* 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 (когда не сказано явно), будет использовать свои внутренние стили, которые обернут ваш пользовательский макет в нем (без полноэкранного режима и т. д.).

и макет? Нет hacky путь не требуется, это работает просто отлично:

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

наслаждайтесь

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

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

просто используйте эту тему внутри 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.Р. стиль.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>

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

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

  1. перейти в Редактор тем (доступно в разделе Инструменты - > Android - > редактор тем)
  2. выберите Показать все темы. Выберите один с AppCompat.Диалоговое окно
  3. выберите опцию android window background, если вы хотите, чтобы он имел какой-либо определенный цветной фон или прозрачный.
  4. выберите цвет и нажмите ЛАДНО.Выберите имя новой темы.
  5. на стили.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>

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

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

    @ Override public void onCreate(@Nullable Bundle savedInstanceState) { супер.onCreate(savedInstanceState); setStyle (DialogFragment.STYLE_NORMAL, R. style.DialogTheme); }

создать под тему в вашем стиле.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>

затем установите стиль в DialogFragment

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

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){}

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

используя 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);
}