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