2013-10-01 10 views
9

私のアプリケーションではViewPagerがあり、そのViewPagerには約17個のフラグメントがあります。私はポートレートと風景のレイアウトをデザインしました。 私の画面を回転させると、getView()というメソッドがヌルオブジェクトを返すと、どうしてこのようなことが起こるのか分かりません。setRetainInstance(true)を使用しましたが、それと同じことですが、PagerStateFragmentAdapterをアダプタの実装として使用しています。getView()内でnullを返すViewPager内のフラグメント

どうしてですか?

ありがとうございます。

EDIT

MainActivity

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)); 
     } 
    } 
} 

BookPageFragment

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); 
} 

}

LOGCAT

09-30 22:56:37.602: E/AndroidRuntime(7640): FATAL EXCEPTION: main 
09-30 22:56:37.602: E/AndroidRuntime(7640): java.lang.NullPointerException 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at com.mobimanage.kagadventures.fragment.BookPageFragment.loadHighlighters(BookPageFragment.java:68) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at com.mobimanage.kagadventures.fragment.BookPageFragment.initHighlightersList(BookPageFragment.java:275) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at com.mobimanage.kagadventures.fragment.BookPageFragment.initAudioPlayback(BookPageFragment.java:257) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at com.mobimanage.kagadventures.fragment.BookPageFragment.startWithRead(BookPageFragment.java:149) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at com.mobimanage.kagadventures.fragment.BookPageFragment.configureBookPage(BookPageFragment.java:298) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at com.mobimanage.kagadventures.fragment.BookPageFragment.onResume(BookPageFragment.java:140) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at com.mobimanage.kagadventures.MainActivity$1.onPageSelected(MainActivity.java:136) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.support.v4.view.ViewPager.scrollToItem(ViewPager.java:567) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:551) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.support.v4.view.ViewPager.onTouchEvent(ViewPager.java:2008) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.view.View.dispatchTouchEvent(View.java:7253) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2168) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1903) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2215) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1458) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.app.Activity.dispatchTouchEvent(Activity.java:2410) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2163) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.view.View.dispatchPointerEvent(View.java:7433) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3220) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3165) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4292) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4271) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4363) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:179) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.os.MessageQueue.nativePollOnce(Native Method) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.os.MessageQueue.next(MessageQueue.java:125) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.os.Looper.loop(Looper.java:124) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at android.app.ActivityThread.main(ActivityThread.java:5227) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at java.lang.reflect.Method.invokeNative(Native Method) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at java.lang.reflect.Method.invoke(Method.java:511) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562) 
09-30 22:56:37.602: E/AndroidRuntime(7640):  at dalvik.system.NativeStart.main(Native Method) 
+0

それぞれのコードを投稿できますか? –

+0

完了!コードは – NemesisDoom

+0

です。これは問題ありません。 PagerStateFragmentAdapterをシードする必要があります。 –

答えて

23

代わりに、現在のページの使用を取得するためのgetItemを使用しての

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

これは実際にビューを持っている既存のフラグメントへの参照を返します。通常のよう

+1

小さなアドバイス:最初の 'mBookPager'はアダプター、もう1つはviewPager – Ron

+0

問題は2つあります:まず、オーバーライドされたinstantiateItem()に依存しています。前のフラグメントを作成しますが、新しいフラグメントを作成します。第2に、ビューを第1引数として参照する呼び出しは非推奨です。 - 私は実用的な解決策を見つけました。答えとして投稿します。 –

+0

あなたは私の日を救った! –

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(); 
+0

これは本当に機能しますか? Androdはフラグメントを破棄することに決めましたが、それはフラグメントの配列に残っていて、後で再作成すると、配列に古いバージョンがあります。私はまだこれが起こることは確かではない。 –

2

setRetainInstanceはandroid.support.v4.app.FragmentManagerでは無視されます。

私のために働いた解決策は、私の活動のonCreateで保存された断片を取り除くことでした。なぜなら、super.OnCreateが呼び出されるからです。

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

これは私がsetRetainInstance(true);が断片的に自分自身を動作するように期待されるように、私のために働きました。

私は、このソリューションhere

*あなたはフラグメントのいずれかからDialogFragmentに呼び出している場合は、このソリューションを使用している場合、彼らは姿勢変化に却下されることに注意してくださいました。

関連する問題