-1

I'm using a FragmentPagerAdapter in the MainActivity. I use res\layout\fragment_text.xml file to create two fragments each with different data entered by the user. When I try to findViewById(), It returns data from a different fragment. Here is the applicable code:

    //this is from my public class SectionsPagerAdapter extends FragmentPagerAdapter 

    @Override
    public Fragment getItem(int position) {
        // getItem is called to instantiate the fragment for the given page.
        switch (position){
            case 0:  return MultipleChoiceSingleAnswerFragment.newInstance(position + 1);
            **case 1:  return TextFragment.newInstance("1", "2");**
            **case 2:  return TextFragment.newInstance("10", "20");**
            case 3:  return ScoreFragment.newInstance("100", "200");
            default: return null;
        }
    }

 //here I collect the fragment tags as they are being instantiated

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Fragment newFragment = (Fragment) super.instantiateItem(container, position);
        // save the appropriate fragment tag depending on position
        fragmentTags[position] = newFragment.getTag();//store in array of Strings
        return newFragment;
    }

In an onclick listener I try to retrieve the fragment and show text that the user entered, into an EditText view, using a toast. This code is called in another Fragment that has just a TextView and a Button

public void onScorePressed(){
       int pageCount = mSectionsPagerAdapter.getCount();
    **TextFragment textfragment = (TextFragment) getSupportFragmentManager().findFragmentByTag(fragmentTags[1]);
    CharSequence text = textfragment.getAnswer()**;<<<<<main problem in call,see below
    int duration = Toast.LENGTH_SHORT;
    Context context = getApplicationContext();
    Toast toast = Toast.makeText(context, text, duration);
    toast.show();

}

In line above `textfragment.getAnswer()' calls this method which exists in two instances of the same fragment class:

public class TextFragment extends Fragment {
    //other code for building a Fragment
 .....
//This method return text entered by user as well as the mParam1 used in the instantiation above in Fragment getItem case 1:; 
public CharSequence getAnswer(){
    EditText txt = (EditText) root.findViewById(R.id.text_answer);
    return "mParam1=" + mParam1 + "text_answer=" + txt.getText();
}

The getAnswer method returns

"mParam1=1 text_answer=text entered"

from the second TextFragment instantiated in case 2 above. This shows that I'm actually getting the correct TextFragment because mParam1 matches the parameter passed in the instantiation. I need a better way to get the EditText View's text. Any help is appreciated. Thanks. Posts I used in my research:

https://stackoverflow.com/a/12805033/9226205
https://developer.android.com/guide/components/fragments.html
https://developer.android.com/reference/android/support/v4/app/FragmentManager.html

Jason
  • 1
  • 3
  • No need to use `getFragmentByTag()`, just keep references to the fragments that you get in the `instantiateItem()` override. – Daniel Nugent Jan 16 '18 at 20:30
  • This is not an answer to my question. I do not get a null pointer exception. I get a fragment back but its the wrong one. My code uses 1 layout.xml file to create two pages/fragments with the same layout but different data. I can only retrieve the second instance no matter which tag I use. – Jason Jan 16 '18 at 20:34
  • I just tried the method mentioned in https://stackoverflow.com/questions/36503779/refresh-data-in-viewpager-fragment but I still get thee same results. Both fragments have the data from the second one instantiated. – Jason Jan 16 '18 at 20:53
  • Show your `newInstance()` method in TextFragment. It looks like maybe you're only creating one instance of TextFragment, when you should have multiple instances. – Daniel Nugent Jan 16 '18 at 22:44
  • @DanielNugent I have two fragments for sure as I can change the index to get the second one. newInstance() only creates one fragment but it is called twice. `public static TextFragment newInstance(String param1, String param2) { TextFragment fragment = new TextFragment(); Bundle args = new Bundle(); args.putString(ARG_PARAM1, param1); args.putString(ARG_PARAM2, param2); fragment.setArguments(args); return fragment; }` – Jason Jan 17 '18 at 01:19

1 Answers1

1

You don't have tags set for your fragments and that's why you can't retrieve the fragments by tag. As far as I know, fragment tag can only be set in the XML layout or when the fragment is created using transaction's add or replace methods. I would expect a NullPointerExeption in

fragmentTags[position] = newFragment.getTag();

since the tag was not previously set.

As a solution, I suggest an array that holds references to your fragments, instead of an array of tags:

Fragment[] fragments = new Fragment[NUMBER_OF_FRAGMENTS];

So getItem method could look like this:

    @Override
    public Fragment getItem(int position) {
    // getItem is called to instantiate the fragment for the given page.
       Fragment fragment;    
       switch (position){
          case 0:  
            fragment = MultipleChoiceSingleAnswerFragment.newInstance(position + 1);
            break;
          case 1:  
            fragment = TextFragment.newInstance("1", "2");
            break;
          case 2:  
            fragment = TextFragment.newInstance("10", "20");
            break;
          case 3:  
            fragment = ScoreFragment.newInstance("100", "200");
          default: 
            fragment = null;
      }
      fragments[position]=fragment;
      return fragment;
    }

Then you can completely omit instantiateItem method because it is not needed.

Finally, in onScorePressed method you get the reference to the right fragment by

TextFragment textfragment = fragments[i];

Hope this helps.

colens
  • 467
  • 3
  • 12
  • Please see my edits. I am getting the correct Fragment. The problem is when I try to get text from EditText view by using getViewById. Also, I did what you suggested but still have the same issue as mentioned. Thanks for your input. Please review my post again if you have time. – Jason Jan 17 '18 at 01:02
  • If you just need the text from the EditText, why don't you just return txt.getText() instead of "mParam1=" + mParam1 + "text_answer=" + txt.getText() ? – colens Jan 17 '18 at 06:45
  • Returning the mParam was just a debugging technique. It showed that my problem was not with getFragmentByTag but with the getting of the text in the fragment by using getViewById. At least that's what I thought. It started working today and I can't say why. Thanks for your input. – Jason Jan 17 '18 at 15:38