1

Trying to learn Android development by poking around so please forgive if the query is too simple.

I have the following code which keeps crashing due to NullPointerException - I hve tried several ways to access the View of the Fragment but I always get null. Can anyone help me out with what I'm doing wrong?

What I'm trying to do is save the contents of the EditText to SharedPreferences when the page is scrolled. For the life of me, I can't seem to access the View of the fragment that is loaded when the tab is displayed.

public class ViewPagerAdapter extends FragmentPagerAdapter { final int PAGE_COUNT = 3; // Tab Titles private String tabtitles[] = new String[] { "Profile", "Address", "Security"}; Context context; public ViewPagerAdapter(FragmentManager fm) { super(fm); } @Override public int getCount() { return PAGE_COUNT; } @Override public Fragment getItem(int position) { switch (position) { // Open FragmentTab1.java case 0: CreateUserFragmentProfile fragmenttab1 = new CreateUserFragmentProfile(); return fragmenttab1; // Open FragmentTab2.java case 1: CreateUserFragmentLocation fragmenttab2 = new CreateUserFragmentLocation(); return fragmenttab2; // Open FragmentTab3.java case 2: CreateUserFragmentSecurity fragmenttab3 = new CreateUserFragmentSecurity(); return fragmenttab3; } return null; } @Override public CharSequence getPageTitle(int position) { return tabtitles[position]; } } 

The Fragment code extends Fragment, and does pretty much nothing.

public class CreateUserFragmentSecurity extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { //return super.onCreateView(inflater, container, savedInstanceState); View view = inflater.inflate(R.layout.create_fragment_security, container, false); return view; } public void storeData(){ } } 

The Activity code is as follows:

public class CreateUser extends AppCompatActivity { public SharedPreferences preferences; public SharedPreferences.Editor editor; public View currView; public String fname, lname, dob, gender, email, addr1, addr2, addr3, addrstate, city, passwd, passwdPlain; public Long mobile, pin; //public FragmentPagerAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_create_user); preferences = getSharedPreferences("Reviv", MODE_PRIVATE); editor = preferences.edit(); // Locate the viewpager in activity_create_user.xml final ViewPager viewPager = (ViewPager) findViewById(R.id.pager); // Set the ViewPagerAdapter into ViewPager final FragmentPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager()); viewPager.setAdapter(adapter); viewPager.setOffscreenPageLimit(3); viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { boolean hasChanged = false; switch (position){ // store data on tab switch case 0: // Profile tab //currView = viewPager.getChildAt(viewPager.getCurrentItem()); // returns null currView = adapter.getItem(viewPager.getCurrentItem()).getView(); // crashes, returns null EditText etFname = currView.findViewById(R.id.etFname); fname = etFname.getText().toString(); hasChanged = false; if(!StringUtils.isEmpty(fname)) { editor.putString("fname", fname); hasChanged = true; } if(hasChanged == true) editor.commit(); break; case 1: // Address tab // currView = viewPager.getChildAt(viewPager.getCurrentItem()); // returns null currView = adapter.getItem(viewPager.getCurrentItem()).getView(); EditText etAddr1 = currView.findViewById(R.id.etAddr1); addr1 = etAddr1.getText().toString(); hasChanged = false; if(!StringUtils.isEmpty(addr1)) { editor.putString("addr1", addr1); hasChanged = true; } if(hasChanged == true) editor.commit(); break; case 2: // Security tab //currView = viewPager.getChildAt(viewPager.getCurrentItem()); // returns null currView = adapter.getItem(viewPager.getCurrentItem()).getView(); EditText etPasswd = currView.findViewById(R.id.etPasswd); passwd = etPasswd.getText().toString(); hasChanged = false; if(!StringUtils.isEmpty(passwd)) { editor.putString("passwd", passwd); hasChanged = true; } if(hasChanged == true) editor.commit(); break; } } @Override public void onPageSelected(int position) { // do nothing } @Override public void onPageScrollStateChanged(int state) { // do nothing } }); } } 

My Stack trace is as follows:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference at com.portmanteau.reviv.CreateUser$1.onPageScrolled(CreateUser.java:58) at android.support.v4.view.ViewPager.dispatchOnPageScrolled(ViewPager.java:1921) at android.support.v4.view.ViewPager.onPageScrolled(ViewPager.java:1895) at android.support.v4.view.ViewPager.pageScrolled(ViewPager.java:1833) at android.support.v4.view.ViewPager.scrollToItem(ViewPager.java:690) at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1777) at android.view.View.layout(View.java:19678) at android.view.ViewGroup.layout(ViewGroup.java:6057) at android.support.constraint.ConstraintLayout.onLayout(ConstraintLayout.java:1197) at android.view.View.layout(View.java:19678) at android.view.ViewGroup.layout(ViewGroup.java:6057) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323) at android.widget.FrameLayout.onLayout(FrameLayout.java:261) at android.view.View.layout(View.java:19678) at android.view.ViewGroup.layout(ViewGroup.java:6057) at android.support.v7.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:434) at android.view.View.layout(View.java:19678) at android.view.ViewGroup.layout(ViewGroup.java:6057) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323) at android.widget.FrameLayout.onLayout(FrameLayout.java:261) at android.view.View.layout(View.java:19678) at android.view.ViewGroup.layout(ViewGroup.java:6057) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635) at android.widget.LinearLayout.onLayout(LinearLayout.java:1544) at android.view.View.layout(View.java:19678) at android.view.ViewGroup.layout(ViewGroup.java:6057) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323) at android.widget.FrameLayout.onLayout(FrameLayout.java:261) at com.android.internal.policy.DecorView.onLayout(DecorView.java:758) at android.view.View.layout(View.java:19678) at android.view.ViewGroup.layout(ViewGroup.java:6057) at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2510) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2219) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1405) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6829) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:966) at android.view.Choreographer.doCallbacks(Choreographer.java:778) at android.view.Choreographer.doFrame(Choreographer.java:713) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:952) at android.os.Handler.handleCallback(Handler.java:789) at android.os.Handler.dispatchMessage(Handler.java:98) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6803) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

5
  • If you are just saving the data in SharedPreferences you can do that directly in the fragment itself. Commented Oct 21, 2017 at 13:12
  • I could but the event that triggers the save is an onPageScrolled - basically, saves the contents of the tab to SharedPreferences when the user scrolls to the next tab. Commented Oct 21, 2017 at 14:38
  • Also tried your suggestion by using onPause and onResume but as there are only 3 tabs, they are never called. Any other suggestion for me to try? Commented Oct 23, 2017 at 8:14
  • can you post your layout xml Commented Oct 23, 2017 at 10:49
  • Sure : Activity : pastebin.com/4TwMSK1K Fragment 1 : pastebin.com/qPFsdMZD Fragment 2 : pastebin.com/w8asVrTG Fragment 3 : pastebin.com/He1UTrcP Commented Oct 23, 2017 at 11:19

2 Answers 2

3

Try something like this:

@Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { boolean hasChanged = false; if (positionOffset > 0) { currView = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":" + position).getView(); if (currView != null) { EditText editText = null; if (position == 0) editText = currView.findViewById(R.id.etPasswdPlain); else if (position == 1) editText = currView.findViewById(R.id.etAddr1); else if (position ==2) editText = currView.findViewById(R.id.etFname); if (editText != null) { String value = editText.getText().toString(); Log.d("TAG", "Value is " + value); } } } } 

Note that this will work only if you are doing left to right swipe ( from page 1 to page 2 and page 2 to page 3).

i.e when you are swiping from page 1 to page 2, data in page 1 is saved and

when you are swiping from page 2 to page 3, data in page 2 will be saved.

For right to left swipe assuming that you have to save page 3 data when swiping from page 3 to page 2 and save page 2 data when swiping from page 2 to page 1, you have to do some logic but you can get the idea from here.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks so much. This code worked and i also think I understand how it does what it does . Also, i'm poking around with the offset and got a rough feel of how the RTL swipe can be captured. +1 for the lucid explanation. :)
Hi, I've been able to successfully save all the editTexts from the first 2 fragments to SharedPreferences but the third fragment's Logd is never called no matter which side the swipe is (RTL, LTR). How do I access those when I do an onPageScrolled ? My code is here : pastebin.com/BXfXt9Rs
@kilokahn Check out here for detecting swipe direction.
Got it and managed to fix my code to detect swipe direction. Thanks so much! :)
0

Try calling

((EditText) viewPager.getChildAt(viewPager.getCurrentItem()) .findViewById(R.id.etFname)).getText().toString() 

rather than

adapter.getItem(viewPager.getCurrentItem()).getView(); 

7 Comments

I tried it and I still get an NullPointerException : java.lang.NullPointerException: Attempt to invoke virtual method 'android.text.Editable android.widget.EditText.getText()' on a null object reference
Could you suggest any other alternatives? Is there any particular reason I'm getting the NPE?
I tried the solution I proposed, it worked fine for me. Can you check if viewPager.getChildAt(viewPager.getCurrentItem()) is null or not?
No luck - I keep getting the NPE and crash. Sharing the entire code with you - can you please take a look? Activity - pastebin.com/utaBPhac
I saw the code you shared, looks fine to me. Just need to know if viewPager.getChildAt(viewPager.getCurrentItem()) is null or your Edittext is null.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.