2

我在尝试更新 ViewPager 片段内的片段中的 ListView 时遇到问题。整个场景是 FragmentActivity 就像在 Fragment 之间进行通信的基础一样工作。

具体来说,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 ????

如何解决这个问题?

先感谢您!

4

2 回答 2

2

我实际上在这里认识了我的一些代码。我认为正在发生的事情是你没有检查以确保viewPagerFragment你得到的 s 是 in 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());
        }
    }

但是,我实际上发现,由于我创建 s 的方式,上面的这段代码只对我有效FragmentPagerAdapter,因为我使用 anArrayList来保存我Fragment的 s,它会将它们返回到getItem. 由于Android 破坏了和s ,因此旋转时失败。我建议您查询s以使您的 s 退出,并确保在刷新之前检查每个是否都在,否则将您的标志设置为刷新。这个问题的公认答案是查看您的孩子的正确方法。ActivityFragmentFragmentManagerFragmentViewPagerviewPagerFragmentonResumeViewPagerFragment

于 2013-02-27T21:46:41.763 回答
0

如此处所述,

每个片段,即使是另一个片段的子片段,在添加到片段树时都会收到对 onAttach() 的调用。包含片段的活动作为参数传入。最简单的解决方案可能是将活动保存为片段的成员。然后它在以后需要时可用。

父 Activity 作为 Context 传入,因此您需要将其转换为 Activity。因此,您可以使用以下代码获取嵌套片段的包含活动:

private Activity mHostActivity;
@Override
public void onAttach(Context context) {
    super.onAttach(context);
    mHostActivity = (Activity) context;
}
于 2018-10-10T10:19:36.447 回答