我在尝试更新ViewPager片段内的片段中的ListView时遇到问题。整个场景是FragmentActivity的工作方式类似于片段之间的通信基础。
具体来说,ListFragment单选片段在FragmentActivity中发送一个对象引用,然后重定向到ViewPager片段,而该片段又应该更新它的另一个片段子片段。
所有东西看起来操作都很完美,第一次创建的ViewPager片段显示了我需要的数据,但是当你在ListFragment中选择一行来启动这个过程,同时进入这段代码中的ViewPager片段时,
public void refreshDataWithClassType(ClassType classType) {
Log.d(TAG, "Should refresh data");
FragmentPagerAdapter fragmentPagerAdapter = (FragmentPagerAdapter) viewPager.getAdapter();
for(int i = 0; i < fragmentPagerAdapter.getCount(); i++) {
ExamsListFragment viewPagerFragment = (ExamsListFragment) fragmentPagerAdapter.getItem(i);
if(viewPagerFragment != null) {
// Do something with your Fragment
// Check viewPagerFragment.isResumed() if you intend on interacting with any views.
viewPagerFragment.refreshExams(classType.getClassTypeId());
}
}
}
我只是将消息发送到每个ViewPagerFragment来刷新我的数据(考试)。 但是在我得到NullPointerException一段时间后,我发现在refreshExams方法中,
public void refreshExams(int classTypeId) {
Bundle args = new Bundle();
args.putInt(KEY_POSITION, getArguments().getInt(KEY_POSITION));
args.putInt(KEY_CLASS_TYPE, classTypeId);
setArguments(args);
getRepositoryExams();
if (examsArrayAdapter == null) Log.d(TAG, "ExamsArrayAdapter is NULL");
if (getActivity() == null) Log.d(TAG, "Activity is NULL");
if (examsList.size() == 0) {
examsArrayAdapter.clear();
examsArrayAdapter.notifyDataSetChanged();
} else {
examsArrayAdapter = new ExamsArrayAdapter(getActivity(), R.layout.exam_row_layout, (ArrayList<Exam>) examsList);
listView.setAdapter(examsArrayAdapter);
}
}
现在即使我已经应该拥有Fragment的这个实例,并且第一次创建它是没关系的,
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
rootView = inflater.inflate(R.layout.exams_list_fragment, container, false);
listView = (ListView) rootView.findViewById(R.id.examsListView);
return rootView;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
callBackExamListener = (OnExamSelectedListener) activity;
} catch (ClassCastException ex) {
throw new ClassCastException(activity.toString() + " must implement OnExamSelectedListener");
}
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getRepositoryExams();
examsArrayAdapter = new ExamsArrayAdapter(getActivity(), R.layout.exam_row_layout, (ArrayList<Exam>) examsList);
listView.setAdapter(examsArrayAdapter);
listView.setOnItemClickListener(listRowItemClickListener);
}
getActivity()和examsArrayAdapter为NULL ????
如何解决这个问题?
提前谢谢!
答案 0 :(得分:2)
我实际上是在认识我的一些代码。我认为发生的事情是你没有检查以确保你所获得的viewPagerFragment
是onResume
,并且如果他们距离当前活着超过1页,它们可能会被销毁页。如果viewPagerFragment
不在onResume
中,您需要使用一种方法在viewPagerFragment
上设置一个布尔标记,以便在它进入refreshExams
时调用onResume
FragmentPagerAdapter fragmentPagerAdapter = (FragmentPagerAdapter) viewPager.getAdapter();
for(int i = 0; i < fragmentPagerAdapter.getCount(); i++) {
ExamsListFragment viewPagerFragment = (ExamsListFragment) fragmentPagerAdapter.getItem(i);
if(viewPagerFragment != null) {
// Do something with your Fragment
// Check viewPagerFragment.isResumed() if you intend on interacting with any views.
if(viewPagerFragment.isResumed())
viewPagerFragment.refreshExams(classType.getClassTypeId());
}
}
。
FragmentPagerAdapter
HOWEVER ,我实际上已经发现,由于我创建ArrayList
的方式,上面的代码对我来说效果很好,因为我使用了Fragment
来抓住我的getItem
,它会在Activity
中返回。自从Android销毁Fragment
和FragmentManager
以来,此失败。我建议您查询Fragment
以使ViewPager
退出viewPagerFragment
,并确保检查每个onResume
是否在ViewPager
之前刷新,并设置您的标志以刷新否则。对此question的接受回答是正确方法来查看Fragment
的孩子{{1}}。
答案 1 :(得分:0)
如here所述,
每个片段,即使是另一个片段的子片段,在将它们添加到片段树时,也会收到对onAttach()的调用。包含片段的活动将作为参数传递。最简单的解决方案是将活动另存为片段的成员。然后在以后需要时可用。
父活动作为上下文传递,因此您需要将其强制转换为活动。 因此,您可以使用以下代码获取嵌套片段的包含活动:
private Activity mHostActivity;
@Override
public void onAttach(Context context) {
super.onAttach(context);
mHostActivity = (Activity) context;
}