我有2个片段,分别是MedListFragment和MedDetailFragment。在MedListFragment中,有一个包含医学对象项的列表视图。单击项目时,MedDetailFragment 将打开,其中包含从 MedListFragment 传递的 Medicine 对象。这是 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");
行返回错误,说:
java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法 'android.os.Parcelable android.os.Bundle.getParcelable(java.lang.String('
为什么参数变为空?究竟如何获得捆绑包?任何帮助将不胜感激。
看看这些行
MedDetailFragment medDetailFragment = new MedDetailFragment();
medDetailFragment.setArguments(bundle);
fragmentTransaction.replace(R.id.fragment_container, new MedDetailFragment());
您正在创建两个不同的 MedDetailFragment 对象。并且不传递已在其中添加捆绑包的对象。
更改此行
fragmentTransaction.replace(R.id.fragment_container,medDetailFragment );
你正在传递新对象,这就是为什么你得到他为空
替换以下行
fragmentTransaction.replace(R.id.fragment_container, new MedDetailFragment());
跟
fragmentTransaction.replace(R.id.fragment_container, medDetailFragment);
在行中
MedDetailFragment medDetailFragment = new MedDetailFragment();
medDetailFragment.setArguments(bundle);
您实例化了一个MedDetailFragment
片段,并添加了参数。 到目前为止,所有先决条件都已完成,medDetailFragment
可以使用。 现在是时候将其添加到占位符中了,比如说fragment_container
. 但在行中
fragmentTransaction.replace(R.id.fragment_container, new `MedDetailFragment`())
您使用语句new
使用 default 构造函数再次创建了片段的新实例,该构造函数创建了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
,它更简单且易于调试。
我希望它有所帮助。