简体   繁体   English

使用 SafeArgs 导航到 Fragment 时检查参数是否存在

[英]Check if arguments exists when navigating to Fragment using SafeArgs

I migrated to Navigation Components and since I use Fragments now, I do no longer call onActivityResult() in my Fragment.我迁移到导航组件,因为我现在使用 Fragment,所以我不再在 Fragment 中调用 onActivityResult()。

I defined the arguments that I pass to AddEditTaskFragment and want to send the modified arguments back to the TodayFragment.我定义了传递给 AddEditTaskFragment 的参数,并希望将修改后的参数发送回 TodayFragment。 Since onViewCreated() is called every time I navigate to the TodayFragment, I want to check if I am actually passing arguments to it to save the Task in my DB then.由于每次导航到 TodayFragment 时都会调用 onViewCreated(),因此我想检查我是否真的将参数传递给它以将任务保存在我的数据库中。

Since AddEditTaskFragmentArgs.fromBundle(getArguments()) != null does not work, what is the recommended way to check if a fragment is receiving arguments?由于 AddEditTaskFragmentArgs.fromBundle(getArguments()) != null 不起作用,检查片段是否正在接收参数的推荐方法是什么?

This is how I navigate back to the calling fragment.这就是我导航回调用片段的方式。

AddEditTaskFragmentDirections.ActionAddEditTaskFragmentToHomeFragment action = AddEditTaskFragmentDirections.actionAddEditTaskFragmentToHomeFragment();

action.setTitle(title);
if (id != -1) action.setId(id);
action.setPriority(priority);
action.setAddanote(duedate);
action.setDuedate(remindme);
action.setRemindme(addanote);
action.setModeEdit(modeEdit);

Navigation.findNavController(getView()).navigate(action);

Now I want todo something like:现在我想做类似的事情:

if (AddEditTaskFragmentArgs.fromBundle(getArguments()) != ...?) {
    // Receive data from action
    String title = AddEditTaskFragmentArgs.fromBundle(getArguments()).getTitle().trim();
    int priority = AddEditTaskFragmentArgs.fromBundle(getArguments()).getPriority();
    String duedate = AddEditTaskFragmentArgs.fromBundle(getArguments()).getDuedate();
    String remindme = AddEditTaskFragmentArgs.fromBundle(getArguments()).getRemindme();
    String addanote = AddEditTaskFragmentArgs.fromBundle(getArguments()).getAddanote().trim();
    boolean modeEdit = AddEditTaskFragmentArgs.fromBundle(getArguments()).getModeEdit();
    int id = AddEditTaskFragmentArgs.fromBundle(getArguments()).getId();

    Task task = new Task(title, addanote, priority, duedate, remindme);
    taskViewModel.insert(task);

    Toast.makeText(getContext(), "Task saved.", Toast.LENGTH_SHORT).show();
}

Don't know if you have figured out the answer since but here's how I'm generally doing.不知道您是否已经找到答案,但这是我通常的做法。

In your XML navigation resource file, arguments need to be declared in each of your destination fragments (in your case, it seems to be both fragments as AddEditTaskFragmentArgs is supposed to receive some arguments, modify them and send them back to the TodayFragment ).在您的 XML 导航资源文件中,需要在每个目标片段中声明参数(在您的情况下,它似乎是两个片段,因为AddEditTaskFragmentArgs应该接收一些参数,修改它们并将它们发送回TodayFragment )。 I assume you have something like this:我假设你有这样的事情:

<?xml version="1.0" encoding="utf-8"?>
<navigation>

    <!-- ... -->

    <fragment
        android:id="@+id/actionAddEditTaskFragmentToHomeFragment"
        android:name="...AddEditTaskFragment"
        android:label="..."
        tools:layout="..." >
        <argument
            android:name="id"
            app:argType="integer"
            android:defaultValue="3" />
        <argument
            android:name="title"
            app:argType="string" 
            app:nullable="true" />

            <!-- Other  arguments -->

    </fragment>

    <!-- Other fragments -->

</navigation>

In the source fragment, you can set arguments by using setters (as you did) or pass them directly in the action constructor (it depends of argument types as well as if you specified a default value for them).在源代码片段中,您可以使用 setter 设置参数(就像您所做的那样)或直接在操作构造函数中传递它们(这取决于参数类型以及是否为它们指定了默认值)。 More information can be found in the official documentation .更多信息可以在官方文档中找到。

Since I notice that you did not supply any argument to your constructor, my guess is that you have provided default values for all your arguments.由于我注意到您没有为构造函数提供任何参数,因此我猜测您已经为所有参数提供了默认值。

Then, in your destination fragment AddEditTaskFragment , you can do:然后,在您的目标片段AddEditTaskFragment ,您可以执行以下操作:

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    // Get arguments from bundle, if any
    if (getArguments() != null) {
        AddEditTaskFragmentArgs args = AddEditTaskFragmentArgs.fromBundle(getArguments()); 

        if (args.getTitle() != null) {
            String title = args.getTitle();
        } else {
            // Title is null because it's a String, that we allowed nullable and because user did not set it
        }

        int id = args.getId(); // An int cannot be null and we specified a default value

        // Check other arguments ...
    }
    else {
        // No argument was provided
        // Use default values or throw an error
    }
}

If you absolutely want to be sure to receive arguments, you can use requireArguments() instead.如果您绝对想确保接收参数,则可以使用requireArguments()代替。 This will throw an error at runtime if the Bundle object passed to the fragment is null .如果传递给片段的 Bundle 对象为null这将在运行时抛出错误。 However, this does not prevent that all your arguments won't be null (see the android documentation link above) so you have to perform the checks that really matter for you, just like before:但是,这并不能阻止您的所有参数都不会为空(请参阅上面的 android 文档链接),因此您必须执行对您真正重要的检查,就像以前一样:

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    AddEditTaskFragmentArgs args = AddEditTaskFragmentArgs.fromBundle(requireArguments()); 

    if (args.getTitle() != null) {
        String title = args.getTitle();
    } else {
        // Title is null because it's a String, that we allowed nullable and because user did not set it
    }

    int id = args.getId(); // An int cannot be null and we specified a default value

    // Check other arguments ...
}

Hope that helps :)希望有帮助:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM