【问题标题】:android - after orrientation change target fragment changes in dialog fragmentandroid - 在dialogfragment中方向更改目标片段更改后
【发布时间】:2014-08-25 09:24:58
【问题描述】:

我有一个向选项菜单添加选项的片段。单击此选项时,将打开一个对话框片段。该对话框将原始片段设置为其目标片段。如果在打开对话框片段时没有发生方向更改,则目标片段与预期的一样,但在方向更改后,目标片段将设置为对话片段本身,而不是之前设置的片段。结果,当我尝试将目标片段转换为设置为目标片段的片段时,我得到了一个 classCastException。我需要在我的对话框中获取目标片段,因为它实现了回调(OnStartOrRestartLoader)。 我已经尝试解决这个问题一个多星期了,如果有人能指出我正确的方向,我将不胜感激。由于这是我在这里的第一个问题,如果我排除了一些必要的信息,或者这不是一个合适的问题,我深表歉意。

在实现 OnStartOrRestartLoader 的片段 (VirsārstsFragment) 中,我创建如下对话框:

FragmentManager fm = getChildFragmentManager();
SearchDialogFragment dialog = new SearchDialogFragment();
dialog.show(fm, "searchDialog");
dialog.setTargetFragment(this, DIALOGFRAGMENT);

然后在 SearchDialogFragment 中我执行以下设置回调:

OnStartOrRestartLoader callback = (OnStartOrRestartLoader) getTargetFragment();

Logcat:

08-25 12:15:55.087: E/AndroidRuntime(10057): FATAL EXCEPTION: main
08-25 12:15:55.087: E/AndroidRuntime(10057): Process: com.example, PID: 10057
08-25 12:15:55.087: E/AndroidRuntime(10057): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example/com.example.MainActivity}: java.lang.ClassCastException: com.example.SearchDialogFragment cannot be cast to com.example.OnStartOrRestartLoader
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2224)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2273)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3759)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.app.ActivityThread.access$900(ActivityThread.java:141)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1208)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.os.Handler.dispatchMessage(Handler.java:102)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.os.Looper.loop(Looper.java:136)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.app.ActivityThread.main(ActivityThread.java:5052)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at java.lang.reflect.Method.invokeNative(Native Method)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at java.lang.reflect.Method.invoke(Method.java:515)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at dalvik.system.NativeStart.main(Native Method)
08-25 12:15:55.087: E/AndroidRuntime(10057): Caused by: java.lang.ClassCastException: com.example.SearchDialogFragment cannot be cast to com.example.OnStartOrRestartLoader
08-25 12:15:55.087: E/AndroidRuntime(10057):    at com.example.SearchDialogFragment.onCreateDialog(SearchDialogFragment.java:59)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.support.v4.app.DialogFragment.getLayoutInflater(DialogFragment.java:307)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:942)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1121)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1103)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1901)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.support.v4.app.Fragment.performActivityCreated(Fragment.java:1518)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:962)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1121)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1103)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1901)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:567)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1171)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.app.Activity.performStart(Activity.java:5322)
08-25 12:15:55.087: E/AndroidRuntime(10057):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2187)
08-25 12:15:55.087: E/AndroidRuntime(10057):    ... 13 more

【问题讨论】:

  • 你能发布更多代码吗
  • 你的 UI 是否会随着方向的改变而改变?我的意思是每个方向都有不同的 UI 显示吗?
  • 我不明白。 getTargetFragment() 返回 Fragment,而您正试图将其转换为 OnStartOrRestartLoader。例外非常明显。你想做什么?
  • @Simon 你提到的现在我想到的是真的,但是即使我尝试转换为扩展 Fragment 的 VirsārstsFragment,同样的问题仍然存在。我通过使用 getParentFragment 而不是 getTargetFragment 找到了解决方案。
  • @pvn 相同的用户界面。我以编程方式添加微调器和文本视图,并希望在单击肯定按钮后保留它们的内容(这是有效的)

标签: android android-fragments android-dialogfragment


【解决方案1】:

setTargetFragment 不应用于建立父/子片段之间的关系。它应该只用于链接 sibling 片段(即存在于同一 FragmentManager 中的片段)。

它在父/子片段之间不起作用的原因是片段的目标被保存并作为索引恢复到其自己的 FragmentManager。因此,在框架在例如方向更改之后恢复 Activity 之前,一切都会变得很糟糕。此时,FragmentManager 将在其自身而不是父 FragmentManager 中查找目标片段。

【讨论】:

    【解决方案2】:

    我仍然不明白为什么 getTargetFragment() 对我不起作用,但是用 getParentFragment() 替换它解决了我的问题。

    【讨论】:

    【解决方案3】:

    这已经很晚了,但我今天遇到了这个问题,并认为我会写下我的解决方案以防有人需要它。

    这里的问题是您将 VirsārstsFragment 的 ChildFragmentManager 传递给 SearchDialogFragment。

    FragmentManager fm = getChildFragmentManager();
    SearchDialogFragment dialog = new SearchDialogFragment();
    dialog.show(fm, "searchDialog");
    

    相反,您需要传递普通的片段管理器(使用 getFragmentManager() 获取)。

    我认为您的代码不是因为在恢复时,因为系统在 childFrgamentManager 中查找 VirsārstsFragment 您传递给 SearchDialogFragment 但由于 VirsārstsFragment 实际上在活动的片段管理器中而无法找到它。将 Activity 的片段管理器传递给 SearchDialogFragment 可以解决此问题。

    【讨论】:

      【解决方案4】:

      如果没有 UI 更改,您可以将属性 configChanges 添加到清单中的活动

      <activity
              android:name=".YourActivity"
              android:configChanges="screenSize|orientation"/>
      

      它的作用是指定在活动本身处理屏幕大小或方向更改时配置更改(在您的情况下没有更改,因此无需执行任何操作)

      如果您以后需要处理任何更改,您可以在活动中的 onConfigurationChanged() 中执行此操作。

      让我知道这是否适用于您的情况

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-11
        • 1970-01-01
        相关资源
        最近更新 更多