Question

What I'm trying to do:

Have users input data on 3 different fragments, then on the 4th fragment the user will review all data input into the first 3 fragments before submitting to a database.

The issue I'm having:

Every method I've tried to set or get from the EditText's creates a NullPointerException

My question:

For what I'm trying to do, what is the correct method to call for the text value of an EditText from one fragment, and set that text in an EditText in another fragment anytime a page is changed?

Notes:

I've simplified the code down to only reflect one EditText on each fragment for ease of replication and for ease of dissecting code.

Code:

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.widget.EditText;

public class SwipeEnterResults extends FragmentActivity {

ResultsPagerAdapter mResultsPagerAdapter;
ViewPager mViewPager;

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

    mResultsPagerAdapter = new ResultsPagerAdapter(getSupportFragmentManager());
    mViewPager = (ViewPager) findViewById(R.id.pager);      
    mViewPager.setAdapter(mResultsPagerAdapter); 
}

public void onResume() {
    super.onResume();
    //Declare EditText(s)

    final EditText txt1= (EditText) mViewPager.findViewById(R.id.txt1);
    final EditText txt2= (EditText) mViewPager.findViewById(R.id.txt2);
    final EditText txt3= (EditText) mViewPager.findViewById(R.id.txt3);

    final EditText rvw1= (EditText) mViewPager.findViewById(R.id.rvw1);
    final EditText rvw2= (EditText) mViewPager.findViewById(R.id.rvw2);
    final EditText rvw3= (EditText) mViewPager.findViewById(R.id.rvw3);


    mViewPager.setOnPageChangeListener(new OnPageChangeListener() {
        @Override
        public void onPageSelected(int position) {

            rvw1.setText(txt1.getText().toString());
            rvw2.setText(txt2.getText().toString());
            rvw3.setText(txt3.getText().toString());                
        }
        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) { }
        @Override
        public void onPageScrollStateChanged(int arg0) { }
    });
}

public class ResultsPagerAdapter extends FragmentPagerAdapter{

    public ResultsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        Fragment f = new Fragment();

        switch (position) {
        case 0:
            f = new Swipe1();
            break;
        case 1:
            f = new Swipe2();
            break;
        case 2:
            f = new Swipe3();
            break;
        case 3:
            f = new SwipeReviewResults();
            break;
        }

        return f;
    }

    @Override
    public int getCount() {
        return 4;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        switch (position) {
        case 0:
            return getString(R.string.str1);
        case 1:
            return getString(R.string.str2);
        case 2:
            return getString(R.string.str3);
        case 3:
            return getString(R.string.strReview);
        default:
            return "Page " + (position + 1);
        }
    }
}
}
Was it helpful?

Solution 4

I ended up trying a couple things. I added mViewPager.setOffscreenPageLimit(3); and then just put my code in an if statement with a condition of position == 3 and that seems to have solved all my issues with the nullpointerexception. Thanks everyone for the help!

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.widget.CheckBox;
import android.widget.EditText;

public class SwipeEnterResults extends FragmentActivity {

ResultsPagerAdapter mResultsPagerAdapter;
ViewPager mViewPager;

//Declare EditText for reviewing data on Fragment SwipeReviewResults
EditText txt1;
EditText rvw1;
EditText txt2;
EditText rvw2;
EditText txt3;
EditText rvw3;

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

    //Set up ViewPager and allow app to hold prior pages when off screen
    mResultsPagerAdapter = new ResultsPagerAdapter(getSupportFragmentManager());
    mViewPager = (ViewPager) findViewById(R.id.pager);      
    mViewPager.setAdapter(mResultsPagerAdapter);
    mViewPager.setOffscreenPageLimit(3);

    //When SwipeReviewResults is displayed, fill EditText's with data from other fragments
    mViewPager.setOnPageChangeListener(new OnPageChangeListener() {
        @Override
        public void onPageSelected(int position) {

            if (position == 3) {
                //set values to EditTexts to pull data from 3 entry fragments and display in SwipeReviewResults
                EditText txt1 = (EditText) mViewPager.findViewById(R.id.txt1);
                EditText rvw1 = (EditText) mViewPager.findViewById(R.id.rvw1);
                EditText txt2 = (EditText) mViewPager.findViewById(R.id.txt2);
                EditText rvw2 = (EditText) mViewPager.findViewById(R.id.rvw2);
                EditText txt3 = (EditText) mViewPager.findViewById(R.id.txt3);
                EditText rvw3 = (EditText) mViewPager.findViewById(R.id.rvw3);


                //Set EditText's on SwipeReviewResults
                rvw1.setText(txt1.getText().toString());
                rvw2.setText(txt2.getText().toString());
                rvw3.setText(txt3.getText().toString());

            }   
        }
        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) { }
        @Override
        public void onPageScrollStateChanged(int arg0) { }
    });
}

public class ResultsPagerAdapter extends FragmentPagerAdapter{

    public ResultsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        Fragment f;

        switch (position) {
        case 0:
            f = new Swipe1();
            break;
        case 1:
            f = new Swipe2();
            break;
        case 2:
            f = new Swipe3();
            break;
        case 3:
            f = new SwipeReviewResults();
            break;
        default:
            f = new Fragment();
            break;
        }

        return f;
    }

    @Override
    public int getCount() {
        return 4;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        switch (position) {
        case 0:
            return getString(R.string.str1);
        case 1:
            return getString(R.string.str2);
        case 2:
            return getString(R.string.str3);
        case 3:
            return getString(R.string.strReview);
        default:
            return "Page " + (position + 1);
        }
    }
}
}

OTHER TIPS

A couple of things:

  1. Is it possible that the EditTexts in the Activity are null because you are trying to reference them (via their IDs in the view) before all of the fragments and their views have been created by the adapter? Furthermore, it would appear that each time the getItem method of the ResultsPagerAdapter is called, a new fragment with its own view is created... so your Activity could be referencing stale EditText views when new fragment views are created.

  2. Your Activity shouldn't have to be concerned with what views are present in each fragment and the logic surrounding them. It would be better to have each fragment handle the reference to its own views and manage the logic surrounding them. What you could do is have a central cache where the EditTexts values are stored/retrieved by the fragments. For instance, in the onPause() method of a Swipe fragment you could store its EditText value in the cache, and in the onResume() method of the SwipeReviewResults fragment could pull all updated EditText values from the cache.

  3. In your switch statement of the adapter, you should make use of the default block to return an empty new Fragment() instead of unnecessarily creating it upfront.

I hope this helps you out.

Don't make the EditTexts final. Try the following code in place of your current onResume:

EditText txt1= (EditText) mViewPager.findViewById(R.id.txt1);
EditText txt2= (EditText) mViewPager.findViewById(R.id.txt2);
EditText txt3= (EditText) mViewPager.findViewById(R.id.txt3);

EditText rvw1= (EditText) mViewPager.findViewById(R.id.rvw1);
EditText rvw2= (EditText) mViewPager.findViewById(R.id.rvw2);
EditText rvw3= (EditText) mViewPager.findViewById(R.id.rvw3);

Probably your ViewPager doesn't have EditTexts with ids R.id.txt1, R.id.rvw1, ...

Insure you have defined all EditTexts in swipe_enter_results.xml file. Otherwise some of objects (maybe all) will be equal to null and you'll get a NullPointerException.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top