Как добавить фрагмент в макет DialogFragment?

У меня есть пользовательский DialogFragment, который содержит макет, некоторые элементы пользовательского интерфейса и макет держателя фрагмента. Что мне нужно сделать, так это раздуть фрагмент содержимого в макет держателя и обеспечить навигацию внутри него. При нажатии кнопки внутри добавленного фрагмента представление перейдет к другому представлению. Фрагмент будет заменен другим в том же холдере, т.е. contentFragment1 покажет некоторые данные, а при нажатии на кнопку предварительного просмотра contentFragment1 заменится на contentFragment2. Я где-то читал, что нельзя заменить фрагмент, жестко запрограммированный на xml, другим. Итак, я пытаюсь добавить contentFragment1 к viewholder из onActivityCreated() фрагмента диалога. Но я получаю сообщение об ошибке, что ресурс, указанный R.id.fragmentHolder, не найден. Что может быть возможной причиной?

Вот мой код для DialogFragment:

public class MyDialog extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    Dialog customDialog = new Dialog(getActivity());
    customDialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
    customDialog.setContentView(R.layout.reports_dialog);
    return customDialog;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    android.app.FragmentTransaction fragmentTransaction =getFragmentManager().beginTransaction();
    fragmentTransaction.add(R.id.myFragmentHolder, new ReportsListFragment());
    fragmentTransaction.commit();
    super.onActivityCreated(savedInstanceState);
}

введите здесь описание изображения

<?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="400dp"
    android:background="@android:color/transparent" >


    <TextView
        android:id="@+id/textView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:text="This is my header text view for the Dialog"
        android:textSize="18sp" />

<RelativeLayout
    android:id="@+id/myFragmentHolder"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@+id/headerlayout" >

</RelativeLayout>


person Ajith Memana    schedule 21.01.2014    source источник
comment
опубликовать макет R.layout.reports_dialog, а также   -  person vipul mittal    schedule 21.01.2014


Ответы (5)


Перепробовав много, я пришел к выводу, что onCreateDialog() не имеет представления, оно просто устанавливает представление при вызове setView().

Вот почему при добавлении динамического (тег framelayout) или статического фрагмента (тег фрагмента) в макет диалогового фрагмента выдается ошибка no parent view или duplicate id.

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

person Raghav Sharma    schedule 17.06.2015
comment
Это очень полезно, спасибо! Просто реализация этого метода и возврат представления помогли мне. - person Eric B.; 30.03.2016
comment
В этом случае помогло использование getChildFragmentManager() вместо getFragmentManager(). - person Brandon; 05.10.2016

R.id.myFragmentHolder расширяется до макета диалогового окна, а getFragmentManager() возвращает менеджер для действия, поэтому не может найти представление.

С вложенными фрагментами в уровне API 17 вы можете использовать getChildFragmentManager().

person Fox    schedule 09.08.2014
comment
Для уровня API ‹ 17 в библиотеке поддержки доступен getChildFragmentManager(). См. stackoverflow.com/a/23640194/1617737. - person ban-geoengineering; 22.01.2017

Просто убедитесь, что макет report_dialog содержит макет, чей идентификатор myFragmentHolder подобен этому

<FrameLayout
android:id="@+id/fragment_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" />
person youssefhassan    schedule 21.01.2014

Просто для справки, поскольку Брэндон упоминает, что правильный ответ - использовать getChildFragmentManager(), имея в виду, что андроид также восстановит состояние фрагментов.

Правильный код для добавления вашего первого фрагмента:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // if the saved instance isn't null, the fragment state will be restored by android
    if (savedInstanceState == null) {
        getChildFragmentManager().beginTransaction().add(R.id.myFragmentHolder, new ReportsListFragment()).commit();
    }
}

после добавления представления. Позже используйте replace, если одновременно должен отображаться только один фрагмент.

Я бы также рекомендовал вызывать transaction.addToBackStack(null);, если кнопка возврата Android должна поддерживаться.

person Paul    schedule 10.01.2017

идентификатор держателя фрагмента в макете - fragmentHolder, и вы используете myFragmentHolder в коде, попробуйте заменить его на:

 fragmentTransaction.add(R.id.fragmentHolder, new ReportsListFragment());
person vipul mittal    schedule 21.01.2014
comment
Ой. Мне жаль. Я отредактировал xml, чтобы сделать его компактным, и случайно переименовал идентификатор при копировании кода в stackoverflow. Идентификатор правильно указывает в моем коде. Но он все еще показывает ту же ошибку. - person Ajith Memana; 22.01.2014