getArguments возвращает ноль при передаче данных между фрагментами - PullRequest
0 голосов
/ 21 сентября 2019

У меня есть 2 фрагмента, которые называются MedListFragment и MedDetailFragment.В MedListFragment есть список с элементами объекта Медицина.При щелчке по элементу MedDetailFragment откроется с объектом Medicine, переданным из MedListFragment. Это прослушиватель щелчка по элементу в MedListFragment.

MedListFragment

medlist = (ListView) root.findViewById(R.id.medlist);

medlist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
        Medicine med = (Medicine) adapterView.getItemAtPosition(i);

        FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        Bundle bundle = new Bundle();
        bundle.putParcelable("medicine", med);

        MedDetailFragment medDetailFragment = new MedDetailFragment();
        medDetailFragment.setArguments(bundle);

        fragmentTransaction.replace(R.id.fragment_container, new MedDetailFragment());
        fragmentTransaction.addToBackStack(null);
        fragmentTransaction.commit();
    }
});

Затем в MedDetailFragment я получаю такой пакет:

public class MedDetailFragment extends Fragment {

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        ViewGroup root = (ViewGroup) inflater.inflate(R.layout.fragment_med_detail, container, false);

        Bundle bundle = getArguments();

        Medicine medicine = bundle.getParcelable("medicine");

        return root;
    }
}

Но в строке возвращается ошибка Medicine medicine = bundle.getParcelable("medicine"); say:

java.lang.NullPointerException: попытка вызвать виртуальный метод 'android.os.Parcelable android.os.Bundle.getParcelable (java.lang.String)' для ссылки на нулевой объект

Почему аргументы обнуляются?Как именно получить комплект?Любая помощь будет оценена.

Ответы [ 3 ]

2 голосов
/ 21 сентября 2019

Взгляните на эти строки

MedDetailFragment medDetailFragment = new MedDetailFragment();
medDetailFragment.setArguments(bundle);

fragmentTransaction.replace(R.id.fragment_container, new MedDetailFragment());

Вы создаете два разных объекта MedDetailFragment.И не передавая объект, в который вы добавили пакет.

Изменить эту строку

fragmentTransaction.replace(R.id.fragment_container,medDetailFragment );
0 голосов
/ 21 сентября 2019

В строках

MedDetailFragment medDetailFragment = new MedDetailFragment();
medDetailFragment.setArguments(bundle);

Вы создали экземпляр MedDetailFragment фрагмента и добавили свои аргументы.На данный момент все предпосылки выполнены, и medDetailFragment готов к использованию.Теперь пришло время добавить его к заполнителю, скажем fragment_container.Но в строке

fragmentTransaction.replace(R.id.fragment_container, new `MedDetailFragment`())

вы снова создали новый экземпляр фрагмента с помощью оператора new, используя конструктор по умолчанию, который создает чистый экземпляр фрагмента MedDetailFragment без дополнительных данных (bundleобъект).Очевидно, что вызов getArguments() для этого экземпляра фрагмента пытается вызвать несуществующую часть фрагмента, в результате чего получается java.lang.NullPointerException.

Решение:

В MedListFragment классе вы должны добавить дополнительный оператор new MedDetailFragment() в строке

fragmentTransaction.replace(R.id.fragment_container, new MedDetailFragment());

с medDetailFragment, который вы создали ранее.

Оптимизация:

Настоятельно рекомендуется использовать фабричный метод в случае работы с Fragments.Для этого класс MedDetailFragment должен выглядеть следующим образом:

public class MedDetailFragment extends Fragment {

    public MedDetailFragment() {
        // Required empty public constructor
    }

    public static MedDetailFragment newInstance(Medicine med) {
        Bundle bundle = new Bundle();
        bundle.putParcelable("medicine", med);
        MedDetailFragment medDetailFragment  = new MedDetailFragment();
        medDetailFragment.setArguments(bundle);
        return medDetailFragment;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        ViewGroup root = (ViewGroup) inflater.inflate(R.layout.fragment_med_detail, container, false);

        Bundle bundle = getArguments();

        Medicine medicine = bundle.getParcelable("medicine");

        return root;
    }
}

, а в классе MedListFragment вы должны просто заменить две строки

MedDetailFragment medDetailFragment = new MedDetailFragment();
medDetailFragment.setArguments(bundle);

только одной строкой кода:

MedDetailFragment medDetailFragment = MedDetailFragment.newInstance(med);

Этот подход заключает в себе механизм внутри класса MedDetailFragment, его гораздо проще и легче отлаживать.

Надеюсь, это поможет.

0 голосов
/ 21 сентября 2019

вы передаете новый объект, поэтому вы получаете ноль

замените следующую строку

fragmentTransaction.replace(R.id.fragment_container, new MedDetailFragment());

на

fragmentTransaction.replace(R.id.fragment_container, medDetailFragment);
...