ViewPager中的片段在getView()中返回null

时间:2013-10-01 03:47:26

标签: android fragment

在我的应用程序中,我有一个ViewPager,在ViewPager里面有大约17个碎片。我为Portrait和Landscape设计了布局。 当我旋转我的屏幕时,方法getView()返回一个空对象,不知道为什么会发生这种情况,我使用了setRetainInstance(true),但仍然是同样的事情,我正在使用{{ 1}}作为我的适配器实现。

为什么会这样?

提前谢谢。

修改

MainActivity

PagerStateFragmentAdapter

BookPageFragment

public class MainActivity extends FragmentActivity implements ViewPagerController{
    public static final String READ_TYPE = "Read_type";
    private static final String TAG = MainActivity.class.getSimpleName();
    private int mReadType;
    private ViewPager mBookPager;

    @Override
    public void goToNextPage() {
        // TODO Auto-generated method stub
        int currentPage = mBookPager.getCurrentItem();
        if(currentPage+1 < mBookPager.getAdapter().getCount()){
            FragmentPagerAdapter adapter = (FragmentPagerAdapter)mBookPager.getAdapter();
            BookPageFragment bookPage = (BookPageFragment)adapter.getItem(currentPage);
            bookPage.setCurrentPage(false);

            bookPage = (BookPageFragment)adapter.getItem(currentPage+1);
            bookPage.setCurrentPage(true);
            mBookPager.setCurrentItem(currentPage+1, true);
        }
    }

    @Override
    public void goToPreviousPage() {
        // TODO Auto-generated method stub
        int currentPage = mBookPager.getCurrentItem();
        if(currentPage >= 0){
            mBookPager.setCurrentItem(currentPage-1,true);
        }
    }

    @Override
    public void onBackPressed() {
        // TODO Auto-generated method stub
        finish();
        overridePendingTransition(R.anim.anim_move_to_right,R.anim.anim_from_left_to_right);
    }

    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        Log.i(TAG,"onDestroy");
        mBookPager.removeAllViews();
        mBookPager = null;
        super.onDestroy();
    }

    @Override
    protected void onCreate(Bundle arg0) {
        // TODO Auto-generated method stub
        super.onCreate(arg0);
        setContentView(R.layout.main_layout);
        overridePendingTransition(R.anim.anim_from_right_to_left, R.anim.anim_move_to_left);
        initReadType();
        mBookPager = (ViewPager)findViewById(R.id.mainLayout_mainViewPager);
        initViewPager();

    }

    private void initReadType(){
        mReadType = getIntent().getIntExtra(READ_TYPE, -1);
    }

    private void initViewPager(){
        BookPagerAdapter mPagerAdapter = new BookPagerAdapter(getSupportFragmentManager(),mReadType);
        ((BookPageFragment)mPagerAdapter.getItem(0)).setCurrentPage(true);
        mBookPager.setAdapter(mPagerAdapter);
        mBookPager.setOnPageChangeListener(mOnPageChangeListener);
    }

    private OnPageChangeListener mOnPageChangeListener = new OnPageChangeListener(){

        @Override
        public void onPageScrollStateChanged(int arg0) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onPageSelected(int selection) {
            // TODO Auto-generated method stub
            BookPagerAdapter bookAdapter = (BookPagerAdapter)mBookPager.getAdapter();
            BookPageFragment fragment = (BookPageFragment)bookAdapter.getItem(selection);
            if(selection > 0){
                bookAdapter.getItem(selection - 1).onPause();
//              bookAdapter.getItem(selection - 1).onDestroy();
            }
            if(selection + 1 < bookAdapter.getCount() && (bookAdapter.getItem(selection + 1) != null)){
                bookAdapter.getItem(selection + 1).onPause();
            }
            fragment.setCurrentPage(true);
            fragment.onResume();
        }

    };

    public static class BookPagerAdapter extends FragmentStatePagerAdapter{
        private List<Fragment> mBookPagesList;
        private int mReadType;

        public BookPagerAdapter(FragmentManager fm,int readType) {
            super(fm);
            // TODO Auto-generated constructor stub
            mReadType = readType;
            initPages();
        }

        @Override
        public Fragment getItem(int position) {
            // TODO Auto-generated method stub
            return mBookPagesList.get(position);
        }

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return mBookPagesList.size();
        }

        private void initPages(){
            mBookPagesList = new ArrayList<Fragment>();
            mBookPagesList.add(FirstPageFragment.newInstance(mReadType));
            mBookPagesList.add(SecondPageFragment.newInstance(mReadType));
            mBookPagesList.add(ThirdPageFragment.newInstance(mReadType));
            mBookPagesList.add(FourthPageFragment.newInstance(mReadType));
            mBookPagesList.add(FifthPageFragment.newInstance(mReadType));
            mBookPagesList.add(SixthPageFragment.newInstance(mReadType));
            mBookPagesList.add(SeventhPageFragment.newInstance(mReadType));
            mBookPagesList.add(EigthPageFragment.newInstance(mReadType));
            mBookPagesList.add(NinethPageFragment.newInstance(mReadType));
            mBookPagesList.add(TenthPageFragment.newInstance(mReadType));
            mBookPagesList.add(EleventhPageFragment.newInstance(mReadType));
            mBookPagesList.add(TwelvethPageFragment.newInstance(mReadType));
            mBookPagesList.add(ThirteenthPageFragment.newInstance(mReadType));
            mBookPagesList.add(FourteenthPageFragment.newInstance(mReadType));
            mBookPagesList.add(FifteenthPageFragment.newInstance(mReadType));
            mBookPagesList.add(SixteenthPageFragment.newInstance(mReadType));
            mBookPagesList.add(SeventeenthPageFragment.newInstance(mReadType));
            mBookPagesList.add(CreditsPageFragment.newInstance(mReadType));
        }
    }
}

}

logcat的

public abstract class BookPageFragment extends Fragment{
public static final String TAG = BookPageFragment.class.getSimpleName();

public static final int AUTO_PLAY = 1;
public static final int READ_WITH_ME = 2;
public static final int READ_TO_MYSELF = 3;

private ViewPagerController mPageController;
protected final static String READ_TYPE_KEY = "readType";

private boolean mIsCurrentPage;

private int mCurrentWordIndex;
private MediaPlayer mMediaPlayer;
private BookPage mBookPage;
private SpeechController mSpeechController;

private TextHighlightController mCurrentHighlightController;
protected List<TextHighlightController> mHighlighters;
private int mCurrentHighlightIndex;

public abstract int getJsonId();
public abstract int getAudioResourceId();
protected abstract int[] getParagraphsTextView();
protected abstract int[] getParagraphsStringRes();
protected abstract int[] getPopupButtonsId();

public BookPageFragment(){
    mIsCurrentPage = false;
    mCurrentHighlightIndex = 0;
}

public void endAudioPlayback(){
    if(getReadTypeFromArgs() == AUTO_PLAY){
        mPageController.goToNextPage();
    }
}

private void loadHighlighters(){
    int[] paragraphsTextViews = getParagraphsTextView();
    int[] stringRes = getParagraphsStringRes();
    for(int i=0;i<paragraphsTextViews.length;i++){
        int currentParagraph = paragraphsTextViews[i];
        int stringId = stringRes[i];
        TextView paragraph = (TextView)getView().findViewById(currentParagraph);
        TextHighlightController controller = TextHighlightController.newInstance(getActivity(), paragraph, stringId);
        addHighlighter(controller);
    }
}

public final void highlightNextWord(){
    if(!mCurrentHighlightController.highlightNextWord()){
        mCurrentHighlightIndex++;
        if(mCurrentHighlightIndex < mHighlighters.size()){
            mCurrentHighlightController = mHighlighters.get(mCurrentHighlightIndex);
            mCurrentHighlightController.highlightNextWord();
        }
    }
}

@Override
public void onAttach(Activity activity) {
    // TODO Auto-generated method stub
    super.onAttach(activity);
    Log.i(TAG,"onAttach");
    try{
        mPageController = (ViewPagerController)activity;
    }catch(ClassCastException e){
        throw new IllegalArgumentException("Activity not implementing ViewPagerController");
    }
}

@Override
public void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    Log.i(TAG,"onCreate");
}

@Override
public void onDetach() {
    // TODO Auto-generated method stub
    super.onDetach();
    resetAll();
    Log.i(TAG,"onDetach");
}

public void goToNextPage(){
    mPageController.goToNextPage();
}

public void goToPreviousPage(){
    mPageController.goToPreviousPage();
}

public void setCurrentPage(boolean isCurrentPage){
    mIsCurrentPage = isCurrentPage;
}

public boolean isCurrentPage(){
    return mIsCurrentPage;
}

@Override
public void onStart() {
    // TODO Auto-generated method stub
    super.onStart();
    Log.i(TAG,"onStart");
}

@Override
public void onResume() {
    // TODO Auto-generated method stub
    Log.i(TAG,"onResume");
    super.onResume();
    resetAll();
    configureBookPage();
}

public final void startWithAutoPlay(){
    disablePopupButtons();
    initAudioPlayback();
}

public final void startWithRead(){
    initAudioPlayback();
}

private long prevWordStartTime = 0;
public final long getNextWordStart(){
    long wordStart=-1;
    if(mCurrentWordIndex < mBookPage.getWordList().size()){
        Word currentWord = mBookPage.getWordList().get(mCurrentWordIndex);
        wordStart = currentWord.getStartTime() - prevWordStartTime;
        wordStart = wordStart + currentWord.getWordLength() - 25;
        prevWordStartTime = currentWord.getEndTime();
        mCurrentWordIndex++;
    }
    return wordStart;
}

public final long getNextWordLength(){
    long wordLength;
    if(mCurrentWordIndex < mBookPage.getWordList().size()){
        Word currentWord = mBookPage.getWordList().get(mCurrentWordIndex);
        if(mCurrentWordIndex == 0){
            wordLength= currentWord.getStartTime();
        }else{
            wordLength = currentWord.getWordLength();
        }
        mCurrentWordIndex++;
    }else{
        wordLength = -1;
    }
    return wordLength;
}

public final void startPlayback(){
    mMediaPlayer = MediaPlayer.create(getActivity(), getAudioResourceId());
    mMediaPlayer.start();
}

@Override
public void onPause() {
    // TODO Auto-generated method stub
    Log.i(TAG,"onPause");
    mIsCurrentPage = false;
    if(mSpeechController != null){
        mSpeechController.stopHighlighting();
    }
    if(mMediaPlayer != null){
        try{
            mMediaPlayer.stop();
            mMediaPlayer.release();
        }catch(Exception e){

        }
    }
    resetHighlighters();
    resetAll();
    super.onPause();
}

@Override
public void onStop() {
    // TODO Auto-generated method stub
    super.onStop();
    Log.i(TAG,"onStop");
}

protected void addHighlighter(TextHighlightController controller){
    if(mHighlighters == null){
        mHighlighters = new ArrayList<TextHighlightController>();
    }
    mHighlighters.add(controller);
}

private void resetHighlighters(){
    if(mHighlighters != null){
        for(TextHighlightController controller : mHighlighters){
            controller.reset();
        }
    }
    mCurrentHighlightIndex = 0;
    mCurrentWordIndex = 0;
}

private void resetAll(){
    mCurrentWordIndex = 0;
    mCurrentHighlightIndex = 0;
    if(mMediaPlayer != null){
        try{
            mMediaPlayer.reset();
        }catch(Exception e){

        }
    }
    if(mCurrentHighlightController != null){
        mCurrentHighlightController.reset();
    }
    if(mSpeechController != null){
        Message msg = mSpeechController.obtainMessage(SpeechController.END_AUDIO);
        mSpeechController.sendMessage(msg);
    }
    if(mHighlighters != null){
        for(TextHighlightController controller : mHighlighters){
            controller.reset();
        }
    }
}

private void initAudioPlayback(){
    if(getJsonId() != 0){
        initHighlightersList();
        loadJson();
        mSpeechController = new SpeechController(this);
        Message msg = mSpeechController.obtainMessage(SpeechController.START_AUTO_PLAY);
        mSpeechController.sendMessageDelayed(msg, 1000);
    }
}

private void disablePopupButtons(){
    if(getView() != null){
        int[] buttonsId = getPopupButtonsId();
        for(int currentButtonId : buttonsId){
            getView().findViewById(currentButtonId).setVisibility(View.INVISIBLE);
        }
    }
}

private void initHighlightersList(){
    loadHighlighters();
    if(mHighlighters != null)
        mCurrentHighlightController = mHighlighters.get(mCurrentHighlightIndex);
}

private void loadJson(){
    Gson gson = new Gson();
    InputStream jsonStream = getResources().openRawResource(getJsonId());
    InputStreamReader jsonReader = new InputStreamReader(jsonStream);
    mBookPage = gson.fromJson(jsonReader, BookPage.class);
}

private void configureBookPage(){
    int currentReadType = getReadTypeFromArgs();
    Log.i(TAG,"GotReadType");
    switch(currentReadType){
    case AUTO_PLAY:
        if(mIsCurrentPage){
            startWithAutoPlay();
        }
        break;
    case READ_WITH_ME:
        if(mIsCurrentPage){
            startWithRead();
        }
        break;
    case READ_TO_MYSELF:
        //Should do Nothing
        break;
    default:
        throw new IllegalArgumentException("You must select one of the reading types of BookPageFragment");
    }
}

protected int getReadTypeFromArgs(){
    return getArguments().getInt(READ_TYPE_KEY);
}

3 个答案:

答案 0 :(得分:28)

而不是使用getItem来获取当前页面

(BookPageFragment) mBookPagerAdapter.instantiateItem(mBookPager, mBookPager.getCurrentItem());

这将返回对实际具有视图的现有片段的引用。

答案 1 :(得分:2)

如果您在页面适配器中跟踪片段,通常会向其添加以下功能:

private SparseArray<PageType> fragments;
...
public PageType getFragment(int position) {
  return fragments.get(position);
}

然后您可以使用它来查询片段。 getView()已经可以在那里工作了:

PageType page = (PageType) pagesAdapter.getFragment(pager.getCurrentItem());
View view = page.getView().findViewById(R.id.whatever);
view.invalidate();

答案 2 :(得分:2)

android.support.v4.app.FragmentManager

会忽略 setRetainInstance

对我有用的解决方案是在调用super.OnCreate之前删除我活动的onCreate中保存的片段。

if(savedInstanceState != null) {
    savedInstanceState.remove("android:support:fragments");
}

这对我有用,我希望setRetainInstance(true);能够在片段中自行工作。

我找到了这个解决方案here

*请注意,如果您从任何片段调用DialogFragment,如果您使用此解决方案,他们将忽略方向更改。