【问题标题】:Android Navigation Component not working with Dialog FragmentsAndroid导航组件不适用于对话框片段
【发布时间】:2020-02-26 09:18:53
【问题描述】:

免责声明:我已经检查了文档,并且自 2.1.0 以来,导航组件已支持对话框片段。 (https://developer.android.com/jetpack/androidx/releases/navigation#2.1.0)

我遇到的错误

我在尝试从 DialogFragment 转到我的 Start Destination 时遇到此错误:

java.lang.IllegalStateException: Fragment PostDistressDialog{829f5d1} (bbbc4926-684b-491b-9772-e0f0ffebe0af)} not associated with a fragment manager.

PostDistressDialog 是使用导航组件从JournalEntryFragment(可以在下面的地图中看到)调用的DialogFragmentPostDistressDialog 不是 JournalEntryFragment 的内部类。它属于自己的扩展类DialogFragment

我的导航图的图片

函数调用导航控制器

public class PostDistressDialog extends DialogFragment implements ISaveDatabase {

...

@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
    if (getArguments()!=null) {

        ...

        // Set up the Alert Dialog
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(getContext());
        alertDialog.setTitle(R.string.distressed_levels);
        alertDialog.setMessage(R.string.distressed_how_feel_post);

        // Inflate and set the layout for the dialog
        View layout = View.inflate(getActivity(), R.layout.dialog_seekbar, null);
        alertDialog.setView(layout);
        
        ....
        // Add okay button
        alertDialog.setPositiveButton(R.string.okay, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                // Save post distress value in Journal Entry
                mJournalEntry.setPostDistress(mTempDistressValue);

                // Save to Journal Entry to database
                // Check if journal entry empty
                if(isJournalEntryEmpty(mJournalEntry)){
                   ...
                }
                else{
                    // Give title if empty
                    if(mJournalEntry.getTitle().isEmpty()) {
                        ....
                    // Save to database
                    new SaveDatabase(getContext(),PostDistressDialog.this).execute(mJournalEntry);
                }

                // Go to main menu
            }
        });

        return alertDialog.create();
    }

    return null;
}

...

@Override
public void databaseSavingCompleted(){
    NavHostFragment.findNavController(this).navigate(PostDistressDialogDirections.postDistressDialogToJournalListAction());
}

}

thispublic class PostDistressDialog extends DialogFragment

我的导航 XML 文件中的对话框

<dialog
    android:id="@+id/postDistressDialog"
    android:name="com.dgrullon.cbtjourney.dialogs.PostDistressDialog"
    android:label="PostDistressDialog" >
    <argument
        android:name="postDistressDialogArguments"
        app:argType="com.dgrullon.cbtjourney.pojo.JournalEntries"/>
    <action
        android:id="@+id/postDistressDialog_to_journalListAction"
        app:destination="@id/journalList"
        app:popUpTo="@id/journalList"
        app:popUpToInclusive="true" />
</dialog>

【问题讨论】:

  • “未与片段管理器关联”表示您的片段不再附加到片段管理器。你在哪里打电话NavHostFragment.findNavController(this)
  • 感谢@ianhanniballake 的快速回复。我编辑了我的答案以显示更多我的DialogFragments 代码。我在其onPostExecute() 方法内的另一个AsyncTask 类中调用NavHostFragment.findNavController(this)。导航组件不是取消片段管理器和导航组件“管理”所有片段吗?

标签: android android-fragments android-navigation android-navigationview


【解决方案1】:

当您添加到setPositiveButton 的回调被触发时,AlertDialog 会自动关闭对话框(并因此删除您的DialogFragment)。因为您正在异步工作,所以在 DialogFragment 被销毁、与 FragmentManager 分离并从 NavController 中删除之后调用您的 databaseSavingCompleted 方法 - 您正在泄漏对 DialogFragment 的引用(否则它将被垃圾收集) .

因此,当NavHostFragment.findNavController(this) 触发时,所有允许它访问NavController 的钩子都已被清除。

如果您不希望按钮立即关闭对话框,则需要将null 传递给setPositiveButton(),并在创建对话框后通过调用其getButton() API 来获取对按钮的引用并手动设置一个OnClickListener,它会启动你的AsyncTask(并禁用该按钮以防止它被多次点击)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-19
    • 1970-01-01
    • 2021-08-13
    相关资源
    最近更新 更多