Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fragment inside ViewPager returning null in getView()

In my app, I have a ViewPager, and inside that ViewPager there're about 17 Fragments. I've designed the layouts for both Portrait and Landscape. When I Rotate my Screen, the method getView() its returning a null object, don't know why this happens, I've used setRetainInstance(true), but still the same thing, I'm using a PagerStateFragmentAdapter as my adapter implementation.

Why does this happens?

Thank you in advance.

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)
like image 867
NemesisDoom Avatar asked Oct 01 '13 03:10

NemesisDoom


People also ask

How do I get current fragment on ViewPager?

ViewPager save Fragment in FragmentManager with particular tags, So We can get ViewPager's fragment by FragmentManager class by providing tag. And ViewPager provide tag to each fragment by following syntax : Fragment page = getSupportFragmentManager(). findFragmentByTag("android:switcher:" + R.

How do you call ViewPager fragment from activity?

You'll just need to cast it to the real fragment class if you want to call a specific method. int pos = viewpager. getCurrentItem(); Fragment activeFragment = adapter. getItem(pos); if(pos == 0) ((NPListFragment)activeFragment).

What is ViewPager?

ViewPager is a layout manager that allows the user to flip left and right through pages of data. It is mostly found in apps like Youtube, Snapchat where the user shifts right – left to switch to a screen. Instead of using activities fragments are used.

Is ViewPager deprecated?

This method may be called by the ViewPager to obtain a title string to describe the specified page. This method is deprecated. This method should be called by the application if the data backing this adapter has changed and associated views should update.


2 Answers

Instead of using getItem to get the current page use

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

This returns a reference to the existing fragment which actually does have a view.

like image 57
Barry Irvine Avatar answered Oct 13 '22 17:10

Barry Irvine


If you keep track of your fragments in your page adapter, as is usual, add the following function to it:

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

Then you can use this to query a fragment. And getView() will already work all right there:

PageType page = (PageType) pagesAdapter.getFragment(pager.getCurrentItem());
View view = page.getView().findViewById(R.id.whatever);
view.invalidate();
like image 39
Gábor Avatar answered Oct 13 '22 18:10

Gábor