Android Компонент навигации - зачем добавлять аргументы в график навигации? - PullRequest
1 голос
/ 03 марта 2020

Я следовал учебнику CodingWithMitch код github ) для компонента навигации, но использовал Java вместо Kotlin. Это не принесло никаких проблем, однако.

Мой вопрос, без использования Safe Args, какой смысл добавлять аргументы в nav_graph.xml.

В этом примере для SpecifyAmountFragment требуется аргумент String из предыдущего фрагмента, который называется ChooseRecipientFragment:

Представление проекта nav_graph.xml: image specifyAmmountFragment ----> 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 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();
                }
            }
        });
    }
}

Я получаю пакет в OnCreateView, из которого я принимая обязательный аргумент String, который я объявил в nav_graph.xml. А позже я отправляю эти данные в другом пакете (в bSend.setOnClickListener(...)).

Если я закомментирую все теги <argument> и снова запущу приложение, оно все равно будет работать как это следует (получение данных из одного фрагмента и передача их в другой). Проверка отсутствует, так зачем вообще добавлять эти теги, кроме того, для ясности, может быть?

1 Ответ

0 голосов
/ 03 марта 2020

При использовании компонента архитектуры навигации вы не должны использовать recipient = getArguments().getString("recipient"); Вместо этого вы должны использовать сгенерированный класс места назначения, который должен быть SpecifyAmountFragmentArgs, и получать ваши данные следующим образом: SpecifyAmountFragment.fromBundle(Pass arguments here).getRecipient, что обеспечит безопасность типов.

...