1

我一直在关注 CodingWithMitch 的教程(和github 代码)来导航组件,但使用的是 Java 而不是 Kotlin。然而,这并没有带来任何问题。

我的问题是,在不使用 Safe Args 的情况下,在nav_graph.xml.

在此示例中,SpecifyAmountFragment需要来自上一个 Fragment 的 String 参数,称为ChooseRecipientFragment

设计视图nav_graph.xml连接ChooseRecipientFragment ---->指定AmmountFragment ---->confirmationFragment的设计视图

来自的代码片段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代码:

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();
                }
            }
        });
    }
}

我在 OnCreateView 中接收包,从中获取我在nav_graph.xml. 稍后,我将在另一个包中(在 中bSend.setOnClickListener(...))发送这些数据。

如果我注释掉所有<argument>标签并再次运行该应用程序,该应用程序仍将正常运行(从一个片段接收数据并将其传递给另一个片段)。没有验证,那么为什么要添加这些标签,除了为了清楚起见?

4

1 回答 1

0

当使用导航架构组件时,您不应该使用 recipient = getArguments().getString("recipient"); 相反,您应该使用生成的目标类,SpecifyAmountFragmentArgs并以这种方式获取数据: SpecifyAmountFragment.fromBundle(Pass arguments here).getRecipient这将提供类型安全。

于 2020-03-03T13:42:06.733 回答