Компонент навигации Android - зачем добавлять аргументы в граф навигации?

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

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

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

Вид дизайна nav_graph.xml:  Представление дизайна, соединяющее ChooseRecipientFragment ---- ›defineAmmountFragment ----› confirmFragment

Фрагмент кода из 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, из которого я беру требуемый аргумент String, который я объявил в nav_graph.xml. А позже я отправляю эти данные в другом пакете (в bSend.setOnClickListener(...)).

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


person Andy    schedule 03.03.2020    source источник


Ответы (1)


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

person Samir Spahic    schedule 03.03.2020
comment
Я полагаю, вы имеете в виду плагин SafeArgs, который генерирует эти классы (ConfirmationFragmentArgs) для каждого пункта назначения. Но я спрашиваю, полезна ли часть <argument> в .xml без SafeArgs - person Andy; 03.03.2020
comment
Привет, что передать здесь: (Передайте аргументы здесь) вы можете подробно объяснить @SamirSpahic - person Prajwal Waingankar; 07.10.2020