简体   繁体   English

Android 导航组件 - 为什么要在导航图中添加参数?

[英]Android Navigation Component - Why add arguments in the navigation graph?

I've been following CodingWithMitch's tutorial (and github code ) to Navigation Component, but used Java instead of Kotlin.我一直在关注 CodingWithMitch 的教程(和github 代码)到导航组件,但使用 Java 而不是 Kotlin。 That hasn't brought any issues however.然而,这并没有带来任何问题。

My question is, without using Safe Args, what is the point to adding arguments in the nav_graph.xml .我的问题是,在不使用 Safe Args 的情况下,在nav_graph.xml添加参数有什么nav_graph.xml

In this example, SpecifyAmountFragment requires a String argument from the previous Fragment, called ChooseRecipientFragment :在此示例中, SpecifyAmountFragment需要来自前一个 Fragment 的 String 参数,称为ChooseRecipientFragment

Design View of nav_graph.xml : nav_graph.xml设计视图: 设计视图连接ChooseRecipientFragment---->指定AmmountFragment---->confirmationFragment

Code snippet from the nav_graph.xml :来自nav_graph.xml代码片段:

<fragment
        android:id="@+id/specifyAmountFragment"
        android:name="com.asfartz.navigation_component_basics.SpecifyAmountFragment"
        android:label="fragment_specify_amount"
        tools:layout="@layout/fragment_specify_amount">

        <argument android:name="recipient"
            app:argType="string" />

        <action
            android:id="@+id/action_specifyAmountFragment_to_confirmationFragment"
            app:destination="@id/confirmationFragment"
            app:enterAnim="@anim/slide_in_right"
            app:exitAnim="@anim/slide_out_left"
            app:popEnterAnim="@anim/slide_in_left"
            app:popExitAnim="@anim/slide_out_right"
            app:popUpTo="@id/mainFragment"
            app:popUpToInclusive="false" />
    </fragment>

Java code:爪哇代码:

public class SpecifyAmountFragment extends Fragment {

    private NavController navController;
    private Button bSend, bCancel;
    private String recipient;
    private TextView tvRecipient;
    private TextInputEditText inputAmount;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_specify_amount, container, false);
        bSend = view.findViewById(R.id.send_btn);
        bCancel = view.findViewById(R.id.cancel_btn);
        tvRecipient = view.findViewById(R.id.recipient);
        inputAmount = view.findViewById(R.id.input_amount);

        recipient = getArguments().getString("recipient");

        String messagge = "Sending money to " + recipient;
        tvRecipient.setText(messagge);
        return view;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        navController = Navigation.findNavController(view);

        bSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!TextUtils.isEmpty(inputAmount.getText())) {
                    Money money = new Money(new BigDecimal(inputAmount.getText().toString()));
                    Bundle b = new Bundle();
                    b.putString("recipient", recipient);
                    b.putParcelable("money", money);

                    navController.navigate(R.id.action_specifyAmountFragment_to_confirmationFragment, b);
                } else {
                    Toast.makeText(getActivity(), "Enter an amount", Toast.LENGTH_SHORT).show();
                }
            }
        });

        bCancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (getActivity() != null) {
                    getActivity().onBackPressed();
                } else {
                    Toast.makeText(getContext(), "Activity is null", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

I'm receiving the bundle in OnCreateView, from which I'm taking the required String argument that I've declared in the nav_graph.xml .我在 OnCreateView 中接收包,从中获取我在nav_graph.xml声明的所需 String 参数。 And later on, I'm sending this data forward in another bundle (in the bSend.setOnClickListener(...) ).稍后,我将在另一个包中转发此数据(在bSend.setOnClickListener(...) )。

If I comment out all the <argument> tags and run the app again, the app will still work as it should (receiving the data from one fragment and passing it to another).如果我注释掉所有<argument>标记并再次运行该应用程序,该应用程序仍将正常工作(从一个片段接收数据并将其传递给另一个片段)。 There is no validation, so why add these tags at all, besides for clarity maybe?没有验证,那么除了为了清楚起见之外,为什么还要添加这些标签呢?

When using Navigation architecture component, you are not suppose to use recipient = getArguments().getString("recipient");使用导航架构组件时,您不应该使用recipient = getArguments().getString("recipient"); Instead, you should use generated class of the destination which should be SpecifyAmountFragmentArgs and get your data this way: SpecifyAmountFragment.fromBundle(Pass arguments here).getRecipient which will provide type safety.相反,您应该使用生成的目标类,它应该是SpecifyAmountFragmentArgs并以这种方式获取数据: SpecifyAmountFragment.fromBundle(Pass arguments here).getRecipient这将提供类型安全。

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

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