Android ViewPager获取视图nullpointer异常

时间:2014-01-02 21:18:15

标签: android android-fragments android-viewpager android-fragmentactivity fragmentstatepageradapter

我有support.v4 ViewPager ,我使用 FragmentStatePagerAdapter 来填充片段。

ViewPager中片段的显示按预期工作,但问题是在FragmentActvitiy类中调用getView()函数时获取片段视图。我可以访问所有15个片段并获取参数等。但是当在片段上调用getView()函数时,我得到一个 nullpointer异常,因为第三个片段getView()是null

MyPageAdapter adapter = (MyPageAdapter) pager.getAdapter();
Fragment fragment;

for (int i=0; i<15; i++) {
    fragment = adapter.getItem(i);
    View v = fragment.getView();
    System.out.println("--- FRAGMENT = " + fragment + "   VIEW = " + v);
}

输出:

--- FRAGMENT = MyPrvaPomocFragment{40ede4c8 #0 id=0x7f06000d}   VIEW = android.support.v4.app.NoSaveStateFrameLayout{40f11cb0 V.E..... ......I. 0,0-540,850}
--- FRAGMENT = MyPrvaPomocFragment{40edf7c0 #1 id=0x7f06000d}   VIEW = android.support.v4.app.NoSaveStateFrameLayout{40f16f80 V.E..... ......ID 540,0-1080,850}
--- FRAGMENT = MyPrvaPomocFragment{40ee0998}   VIEW = null

FragmentStatePageAdapter类代码:

public class MyPageAdapter extends FragmentStatePagerAdapter {

    private List<Fragment> fragments;

    public MyPageAdapter(FragmentManager fm, List<Fragment> fragments) {
        super(fm);
        this.fragments = fragments;
    }

    @Override
    public Fragment getItem(int position) {
        return this.fragments.get(position);
    }

    @Override
    public int getCount() {
        return this.fragments.size();
    }

    @Override
    public int getItemPosition(Object object){
        return PagerAdapter.POSITION_NONE;
    }
}

片段类代码:

public class MyPrvaPomocFragment extends Fragment {

    public static final String EXTRA_QUESTION_NUMBER = "EXTRA_QUESTION_NUMBER";
    public static final String EXTRA_QUESTION = "EXTRA_QUESTION";
    ...    

    public static final MyPrvaPomocFragment newInstance(String questionNumber, String question, ..., int correctAnswer) {
        MyPrvaPomocFragment f = new MyPrvaPomocFragment();

        Bundle bdl = new Bundle(1);
        bdl.putString(EXTRA_QUESTION_NUMBER, questionNumber);
        bdl.putString(EXTRA_QUESTION, question);
        bdl.putInt(EXTRA_CORRECT_ANSWER, correctAnswer);
        ...
        f.setArguments(bdl);

        return f;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        String question = getArguments().getString(EXTRA_QUESTION);
        String firstAnswer = getArguments().getString(EXTRA_FIRST_ANSWER);
        ...

        View v = inflater.inflate(R.layout.fragment_prva_pomoc, container, false);

        TextView textViewQuestion = (TextView) v.findViewById(R.id.textViewQuestion);
        CheckBox checkBox1 = (CheckBox) v.findViewById(R.id.checkBox1);
        CheckBox checkBox2 = (CheckBox) v.findViewById(R.id.checkBox2);
        ...

        textViewQuestion.setText(question);
        checkBox1.setText(firstAnswer);
        checkBox2.setText(secondAnswer);

        return v;
    }
}

FragmentActivity类代码:

public class KvizPrvaPomoc extends FragmentActivity {

    ViewPager pager;
    MyPageAdapter pageAdapter;    

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.kviz_prva_pomoc);

        pager = (ViewPager)findViewById(R.id.viewpagerquiz);              
        pageAdapter = new MyPageAdapter(getSupportFragmentManager(), getFragments());
        pager.setAdapter(pageAdapter);
    }  

    private List<Fragment> getFragments(){
        String question;
        String firstAnswer;
        String secondAnswer;
        ...

        List<Fragment> fragmentList  = new ArrayList<Fragment>();

        for (int j=0; j<someList.size(); j++)  { 
            ...  
            fragmentList.add(MyPrvaPomocFragment.newInstance(questionNumber, question, firstAnswer, ...));
        }

        return fragmentList;
    }
}

我已阅读了大量的SO问题/答案,但我不知道会出现什么问题。

2 个答案:

答案 0 :(得分:1)

这是预期的行为;一旦你向任何一个方向滚动多个碎片,FragmentStatePagerAdapter就会破坏碎片。这样做是为了节省内存。

答案 1 :(得分:1)

视图寻呼机自动从内存中删除片段视图。这样做是为了管理移动设备上的资源。

您不应该尝试从活动中访问片段的可视元素。只有片段应该使用自己的可视元素,而不是直接使用它的父活动。

如果您需要操作片段,您应该更改它们保存的数据以及重新创建视图时(当用户滑动到片段时),它应该根据数据正确地恢复视图。