Manas Bajaj
Manas Bajaj

Reputation: 1133

Passing data between two Fragments in a VIewPager (Android) (NullPointerException)

So basically I have 2 Fragments - FragmentConverter and FragmentFavourites, and I have one MainActivity. I'm trying to pass 4 arrays from the first fragment to the second one using an Interface called Communicator. The specific snippets are show below:

public interface Communicator {

    public void respond(String[] names, String[] codes, String[] symbols, int[] images);
}

This is a method inside FragmentFavourites:

@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // TODO Auto-generated method stub

        String[] checkedNames = new String[counter];
        String[] checkedCodes = new String[counter];
        String[] checkedSymbols = new String[counter];
        int[] checkedImages = new int[counter];
        comm = (Communicator) getActivity();
        int index = 0;
        if (item.getItemId() == R.id.action_save){
            for (int i=0;i<checked.size();i++){
                if (checked.get(i) == true){
                    checkedNames[index] = names[i];
                    checkedCodes[index] = codes[i];
                    checkedSymbols[index] = symbols[i];
                    checkedImages[index] = images[i];
                    index++;
                }

            }
            comm.respond(checkedNames, checkedCodes, checkedSymbols, checkedImages);
        }

        return super.onOptionsItemSelected(item);
    }

This is the implemented interface method inside MainActivity:

@Override
public void respond(String[] names, String[] codes, String[] symbols,
        int[] images) {
    // TODO Auto-generated method stub
    FragmentConverter frag = (FragmentConverter) fragmentPagerAdapter.getItem(1);
    frag.changeData(names, codes, symbols, images);
}

And this is a method that collects the data in FragmentConverter:

public void changeData(String[] names, String[] codes, String[] symbols, int[] images){
        this.names = names;
        this.codes = codes;
        this.symbols = symbols;
        this.images = images;

        Log.d("TEST", symbols.length + names.length + codes.length + images.length + "");
        tvOneRate.setText(names[1]); 
}

Now the problem is that whenever I try to change a ui component inside FragmentConverter, I get a NullPointerException, though the Log.d statement returns the correct results.

EDIT1: getItem() method of FragmentPagerAdapter:

@Override
    public Fragment getItem(int i) {
        // TODO Auto-generated method stub
        Fragment frag = null;
        if (i == 0){
            frag = new FragmentFavourites();
        }
        if (i == 1){
            frag = new FragmentConverter();
        }
        return frag;
    }

Upvotes: 2

Views: 7541

Answers (4)

Vikram
Vikram

Reputation: 778

As above carlo.marinangeli has suggested when you call fragmentPagerAdapter.getItem(1) you are getting a new instance of the fragment so you are referring to a different object

So to get same object from you adapter you need to store your object. you can try following method in your adapter -

public Fragment getFragmentAtPosition(int position) {
            return registeredFragments.get(position);
}

where registeredFragments is -

private SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();

and fill this sparseArray in getItem method like below -

@Override
        public Fragment getItem(int position) {
            switch (position) {
                case 0:
                    fragment = FragmentPost.newInstance(position);
                    registeredFragments.put(position, fragment);
                    return fragment;
               }
            return null;
        }

Upvotes: 2

carlo.marinangeli
carlo.marinangeli

Reputation: 3048

EDITED:

When you call fragmentPagerAdapter.getItem(1) you are getting a new instance of the fragment so you are referring to a different object. this is why the view is null and you get the NullPointerException. If you need an adapter for only 2 fragments, you can try with something like that:

public class YourPagerAdapter extends android.support.v4.app.FragmentPagerAdapter {

        private FragmentFavourites mFragFavourites;
        private FragmentConverter mFragConverter;

        public YourPagerAdapter() {

            // ... your code above
            this.mFragFavourites = new FragmentFavourites();
            this.mFragConverter = new FragmentConverter();
        }

        @Override
        public Fragment getItem(int position) {

            switch (position) {
                case 0:  
                    return mFragFavourites;

                case 1:
                    return mFragConverter;                      
                default:
                    return null;
            }    
        }
    }

Upvotes: 6

Manas Bajaj
Manas Bajaj

Reputation: 1133

By using fragmentPagerAdapter.getItem(pos) method I was referring to a new object every time the respond() method was called. I fixed it by using findFragmentByTag() method instead:

    @Override
    public void respond(String[] names, String[] codes, String[] symbols,
            int[] images) {
        FragmentManager manager = getSupportFragmentManager();
        FragmentConverter frag = (FragmentConverter) manager.findFragmentByTag("android:switcher:" + pager.getId() + ":" + 1);
        frag.changeData(names, codes, symbols, images);
    }

Upvotes: 1

Simone Casagranda
Simone Casagranda

Reputation: 1215

you can get that error because you are assuming that you have got the FragmentConverter and the views associated to it.

Without a logcat it becomes a little bit difficult to help you but basically what I would like to do in a situation like this is to pass everything through the activity without letting know the existence of the other fragment to the fragments.

  • F1 modifies a state object into the activity
  • F2 has to register as a listener to the activity (be aware that the fragment can be attached and detached in the view pager)
  • The Activity as soon it receives an updated, looks for all the registered listeners and if there is someone it delivers the updated

Upvotes: 0

Related Questions