2017-10-21 89 views
1

Essayez d'apprendre le développement d'Android en faisant des recherches, alors pardonnez si la requête est trop simple.Impossible d'accéder à View of Fragment avec ViewPager et FragmentPagerAdapter

J'ai le code suivant qui continue à se bloquer en raison de NullPointerException - J'ai essayé plusieurs façons d'accéder à la vue du fragment, mais je reçois toujours null. Quelqu'un peut-il m'aider avec ce que je fais mal? Ce que j'essaie de faire est d'enregistrer le contenu de l'EditText à SharedPreferences lorsque la page est défilée. Pour la vie de moi, je n'arrive pas à accéder à la vue du fragment qui est chargé lorsque l'onglet est affiché. Le code Fragment étend Fragment, et ne fait pratiquement rien.

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(){ 

    } 
} 

Le code d'activité est la suivante:

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

Ma trace Stack est la suivante:

java.lang.NullPointerException: Tentative d'invoquer la méthode virtuelle « android.view .View android.view.View.findViewById (int) 'sur une référence d'objet nul at com.portmanteau.reviv.CreateU ser $ 1.onPageScrolled (CreateUser.java:58) à android.support.v4.view.ViewPager.dispatchOnPageScrolled (ViewPager.java:1921) à android.support.v4.view.ViewPager.onPageScrolled (ViewPager.java : 1895) à android.support.v4.view.ViewPager.pageScrolled (ViewPager.java:1833) à android.support.v4.view.ViewPager.scrollToItem (ViewPager.java:690) à android.support.v4 .view.ViewPager.onLayout (ViewPager.java:1777) à android.view.View.layout (View.java:19678) à android.view.ViewGroup.layout (ViewGroup.java:6057) au android.support.constraint.ConstraintLayout.onLayout (ConstraintLayout.java:1197) at android.view.View.layout (View.java:19678) à android.view.ViewGroup.layout (ViewGroup.java:6057) à android.widget.FrameLayout.layoutChildren (FrameLayout.java:323) à android.widget.FrameLayout.onLayout (FrameLayout.java:261) à android.view.View.layout (View.java:19678) à androïde .view.ViewGroup.layout (ViewGroup.java:6057) à android.support.v7.widget.ActionBarOverlayLayout.onLayout (ActionBarOverlayLayout.java:434) à android.view.View.layout (View.j ava: 19678) à android.view.ViewGroup.layout (ViewGroup.java:6057) à android.widget.FrameLayout.layoutChildren (FrameLayout.java:323) à android.widget.FrameLayout.onLayout (FrameLayout.java: 261) à android.view.View.layout (View.java:19678) à android.view.ViewGroup.layout (ViewGroup.java:6057) à android.widget.LinearLayout.setChildFrame (LinearLayout.java:1791) at android.widget.LinearLayout.layoutVertical (LinearLayout.java: 1635) à android.widget.LinearLayout.onLayout (LinearLayout.java:1544) à android.view.View.layout (View.java:19678) à android.view.ViewGroup.layout (ViewGroup.java: 6057) à android.widget.FrameLayout.layoutChildren (FrameLayout.java:323) à android.widget.FrameLayout.onLayout (FrameLayout.java:261) à com.android.internal.policy.DecorView.onLayout (DecorView. java: 758) à android.view.View.layout (View.java:19678) à android.view.ViewGroup.layout (ViewGroup.java:6057) à android.view.ViewRootImpl.performLayout (ViewRootImpl.java: 2510) à android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:2219) à android.view.ViewRootImpl.doTraversal (ViewRootImpl.java:1405) à android.view.ViewRootImpl $ TraversalRunnable.run (ViewRootImpl.java : 6829) à android.view.Choreographer $ CallbackRecord.run (Choreographer.java:966) à android.view.Choreographer.doCallbacks (Choreographer.java:778) à android.view.Choreographer.doFrame (chorégraphe. java: 713) au android.view.Choreographer $ FrameDisplayEventReceiver.run (Choreographer.java:952) à android.os.Handler.handleCallback (Handler.java:789) à android.os.Handler.dispatchMessage (Handler.java:98) à android.os.Looper.loop (Looper.java:164) à androïde .app.ActivityThread.main (ActivityThread.java:6803) à java.lang.reflect.Method.invoke (Méthode native) à com.android.internal.os.Zygote $ MethodAndArgsCaller.run (Zygote.java:240) à com.android.internal.os.ZygoteInit.main (ZygoteInit.java:767)

+0

Si vous sauvegardez simplement les données dans SharedPreferences, vous pouvez le faire directement dans le fragment lui-même. –

+0

Je pourrais mais l'événement qui déclenche la sauvegarde est un onPageScrolled - en gros, enregistre le contenu de l'onglet à SharedPreferences lorsque l'utilisateur fait défiler l'onglet suivant. – kilokahn

+0

Également essayé votre suggestion en utilisant onPause et onResume mais comme il n'y a que 3 onglets, ils ne sont jamais appelés. Toute autre suggestion pour moi d'essayer? – kilokahn

Répondre

1

Essayez quelque chose comme ceci:

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

Notez que cela ne fonctionnera que si vous êtes faisant, de gauche à glisser vers la droite (de la page 1 à la page 2 et page 2 à page 3).

-à-dire lorsque vous glisser de page 1 à page 2, les données page 1 est enregistré et

lorsque vous glisser de page 2 à la page 3, données page 2 seront sauvegardés.

Pour right to left swipe en supposant que vous devez enregistrer page 3 données lors de glisser de page 3 à la page 2 et enregistrer page 2 données lors de glisser de page 2 à la page 1, vous devez faire un peu logique, mais vous pouvez obtenir l'idée d'ici.

+0

Merci beaucoup. Ce code a fonctionné et je pense aussi que je comprends comment il fait ce qu'il fait. En outre, je fouille avec le décalage et ai une idée approximative de la façon dont le balayage de RTL peut être capturé. +1 pour l'explication lucide. :) – kilokahn

+0

Salut, J'ai réussi à enregistrer tous les editTexts des 2 premiers fragments à SharedPreferences mais le Logd du troisième fragment n'est jamais appelé quel que soit le côté où le balayage est (RTL, LTR). Comment accéder à ceux-ci lorsque je fais un onPageScrolled? Mon code est ici: https://pastebin.com/BXfXt9Rs – kilokahn

+1

@kilokahn Découvrez [ici] (https://stackoverflow.com/questions/13667459/how-to-know-viewpager-is-scroll-left -ou-droite # 26677301) pour détecter la direction de balayage. –

0

Essayez d'appeler

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

plutôt que

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

Je l'ai essayé et je reçois toujours un NullPointerException: java.lang.NullPointerException: Tentative d'invoquer la méthode virtuelle « android.text.Editable android.widget.EditText.getText() » sur un objet nul référence – kilokahn

+0

Pouvez-vous suggérer d'autres alternatives? Y a-t-il une raison particulière pour laquelle je reçois le NPE? – kilokahn

+0

J'ai essayé la solution que j'ai proposée, ça a bien fonctionné pour moi. Pouvez-vous vérifier si viewPager.getChildAt (viewPager.getCurrentItem()) est null ou non? –