如何访问ViewPager中片段内的getActivity()

时间:2013-02-27 13:33:27

标签: java android android-fragments android-viewpager

我在尝试更新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 ????

如何解决这个问题?

提前谢谢!

2 个答案:

答案 0 :(得分:2)

我实际上是在认识我的一些代码。我认为发生的事情是你没有检查以确保你所获得的viewPagerFragmentonResume,并且如果他们距离当前活着超过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销毁FragmentFragmentManager以来,此失败。我建议您查询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;
}