【问题标题】:Using FragmentTransaction with a DialogFragment将 FragmentTransaction 与 DialogFragment 一起使用
【发布时间】:2011-04-08 14:31:26
【问题描述】:

所以我创建了一个 DialogFragment,它通过 technique 显示为对话框

现在它已经启动并且在此弹出窗口中进行用户交互时,我想将另一个片段滑入此对话框。我正在尝试通过 FragmentTransaction.add() 执行此操作,在其中我给它这个布局中一个容器的 id。此时我得到:

java.lang.IllegalArgumentException: No view found for id 0x7f09013f for fragment <fragmentClassThatIWasPushingIn>

作为一个快速测试,我尝试将它推送到一个容器 id 上,而不是在对话框中,而是在主要的支持活动中,并且效果很好。

DialogFragments 及其容器 ID 是否存在不允许 FragmentTransactions 的内容?

作为权宜之计,我告诉我的事务隐藏当前的 DialogFragment 并显示这个新片段,但动画/显示有点不和谐,所以我真的很想解决这个问题。

谢谢

【问题讨论】:

    标签: android android-3.0-honeycomb android-fragments


    【解决方案1】:

    DialogFragment 显示为Dialog 时,它在容器视图中实际上并不是真正的Fragment。它是一个无容器的Fragment,它基本上是一个Dialog 的包装器。

    所以不,您不能在FragmentDialog 中显示Fragment。如果您真的想这样做,我认为最好的方法是创建一个新的Activity,样式为Dialog,然后您也可以添加Fragments

    【讨论】:

    • 这是正确的。但是 DialogFragment 可以通过 setShowsDialog(false); 强制充当 Fragment。检查我的答案。
    【解决方案2】:

    alexanderblom 说 DialogFragment 充当 Dialog 是对的,但是它可以通过 setShowsDialog(false); 充当 Fragment

    最后,以下对我有用:

    文件: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 似乎无法获取容器。

      这可能是一个错误吗?

      【讨论】:

        【解决方案4】:

        使用 commitAllowingStateLoss() 显示 DialogFragment

        DialogFragment.show(FragmentManager 管理器, 字符串标签)在允许状态丢失时没有显示对话框的选项。这有点奇怪和不一致,因为有一个DialogFragment.dismissAllowingStateLoss()。

        但是你总是可以手动提交 DialogFragment 事务,或者创建一个这样的辅助方法:

        public static void showDialogAllowingStateLoss(FragmentManager fragmentManager, DialogFragment dialogFragment, String tag) {
        FragmentTransaction ft = fragmentManager.beginTransaction();
        ft.add(dialogFragment, tag);
        ft.commitAllowingStateLoss();
        }
        

        【讨论】:

          猜你喜欢
          • 2012-06-14
          • 1970-01-01
          • 2020-01-11
          • 2012-04-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-11-26
          • 1970-01-01
          相关资源
          最近更新 更多