Использование FragmentTransaction с помощью DialogFragment
Итак, я создал диалоговое окно DialogFragment, которое показано в виде диалога с помощью этой .
Теперь, когда он запускается и при взаимодействии с пользователем внутри этого всплывающего окна, я хочу переместить его в другой фрагмент. Я пытаюсь сделать это через FragmentTransaction.add(), где я даю ему идентификатор одного из контейнеров в этом макете. На данный момент я получаю:
java.lang.IllegalArgumentException: No view found for id 0x7f09013f for fragment <fragmentClassThatIWasPushingIn>
В качестве быстрого теста я попытался вытолкнуть его на идентификатор контейнера не в диалоговом окне, а в рамках основной операции резервного копирования, и это сработало просто отлично.
Есть ли что-то о DialogFragments и его идентификаторах контейнера, которые не допускают FragmentTransactions?
Как секундомер, я сказал моей транзакции, чтобы скрыть текущий диалог и показать этот новый фрагмент, но анимация/дисплей немного раздражает, поэтому мне очень хотелось бы избавиться от этой проблемы.
Спасибо
Ответы
Ответ 1
Когда a DialogFragment
отображается как Dialog
, он фактически не является реальным Fragment
в представлении контейнера. Это контейнер-меньше Fragment
, который является в основном оберткой Dialog
.
Нет, вы не можете показать Fragment
внутри FragmentDialog
. Если вы действительно этого хотите, я думаю, что лучший способ - создать новый Activity
в стиле Dialog
, который вы также можете добавить Fragments
.
Ответ 2
alexanderblom прав, что DialogFragment
действует как диалог, однако его можно заставить действовать как фрагмент с setShowsDialog(false);
В итоге для меня работало следующее:
Файл: res/layout/wifidirect_dialog_wifidirect:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/dialog_wifidirect_layout">
<LinearLayout
android:id="@+id/frag_container"
android:layout_width="match_parent"
android:layout_height="250dp"
android:orientation="vertical" >
<!-- This is replaced during runtime -->
<RelativeLayout
android:id="@+id/frag_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="top" >
</RelativeLayout>
</LinearLayout>
<!-- The Cancel Button -->
<View
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_marginBottom="0dp"
android:background="?android:attr/dividerVertical" />
<Button
android:id="@+id/dialog_wifidirect_cancel"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/cancel"/>
</LinearLayout>
Файл src/.../WifiDirectDialog.java:
public class WiFiDirectDialog extends DialogFragment {
public static final String TAG = "WifiDirectDialog";
public static final String DEVICE_LIST_FRAGMENT_TAG = "WIFIDIRECT_DEVICE_LIST_FRAGMENT";
public static WiFiDirectDialog newInstance(){
WiFiDirectDialog wDialog = new WiFiDirectDialog();
//We want this Dialog to be a Fragment in fact,
//otherwise there are problems with showing another fragment, the DeviceListFragment
wDialog.setShowsDialog(false);
//wDialog.setStyle(SherlockDialogFragment.STYLE_NORMAL,android.R.style.Theme_Holo_Light_Dialog);
//We don't want to recreate the instance every time user rotates the phone
wDialog.setRetainInstance(true);
//Don't close the dialog when touched outside
wDialog.setCancelable(false);
return wDialog;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.v(TAG,"onCreateView");
View view = inflater.inflate(R.layout.wifidirect_dialog_wifidirect,container, false);
//Log.v(TAG,"FragmentTransaction started");
ListFragment listFragment = new YourListFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.addToBackStack(DEVICE_LIST_FRAGMENT_TAG)
.replace(R.id.frag_list,deviceListFragment,DEVICE_LIST_FRAGMENT_TAG)
.commit();
//Log.v(TAG,"FragmentTransaction finished");
return view;
};
@Override
public void onActivityCreated(Bundle savedInstanceState){
Log.v(TAG,"onActivityCreated");
super.onActivityCreated(savedInstanceState);
Dialog dialog = getDialog();
dialog.setTitle(R.string.wifidirect_dialog_title);
// Set button listeners etc...///
Button cancelButton = (Button) view.findViewById(R.id.dialog_wifidirect_cancel);
cancelButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
dismiss();
}
});
}
Ответ 3
там действительно есть контейнер, как вы можете видеть в методе onCreateView. Вы используете контейнер для создания своего вида.
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle icicle) {
Log.d(TAG, "onCreateView");
View v = inflater
.inflate(R.layout.move_folder_dialog, container, false);
Кажется, что FragmentManager не может получить контейнер.
Может ли это быть ошибкой?