Полный экран 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 и изменить его в соответствии с приведенным выше кодом.
-
Перейдите к классу фрагмента диалога и в методе 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>
Ответ 26
Есть хороший учебник для полноэкранного диалога
https://medium.com/@haxzie/android-full-screen-dialogs-using-dialogfragment-usage-guide-8fd3cc2cabf8