29

I am trying to implement fragment communication in android like the one in the android guide http://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity

but my application is crashing as the getSupportFragmentManager().findFragmentById() returns null. What is the issue with my implementation.

The code is given below:

The program is just to send an input text from one fragment to another fragment textView area through a button click from first fragmnet.I have an activity_main.xml and two fragment layout (two separate xml files rather than part of in activity_main.xml)

Frag1.java

public class Frag1 extends Fragment {
public Frag1(){

}

buttonClickListener buttonListener;

@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
    buttonListener = (buttonClickListener) getActivity();
} catch (ClassCastException e) {
    throw new ClassCastException(activity.toString() + " must implement OnButtonPressListener");
}
}

View myFragmentView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    myFragmentView = inflater.inflate(R.layout.frag1, container, false);


    //SetValue Button
    Button setValueButton = (Button) myFragmentView.findViewById(R.id.setValueButton);
    setValueButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            buttonListener.onButtonPressed("Message received");
        }
    });


    return myFragmentView;
}

}

Frag2.java

public class Frag2 extends Fragment {

View myFragmentView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
 myFragmentView = inflater.inflate(R.layout.frag2, container, false);
    return myFragmentView;
}

void setMessage(String msg){
    TextView txt=(TextView)myFragmentView.findViewById(R.id.textView1);
    txt.setText(msg);
}
}

buttonClickListener.java

public interface buttonClickListener {
public void onButtonPressed(String msg);
}

MainActivity.java

public class MainActivity extends FragmentActivity implements
    ActionBar.TabListener, buttonClickListener {
SectionsPagerAdapter mSectionsPagerAdapter;
@Override
public void onButtonPressed(String msg) {
    // TODO Auto-generated method stub
    Frag2 fragmentObj=(Frag2) getSupportFragmentManager().findFragmentById(R.layout.frag2);


    fragmentObj.setMessage(msg);
}

Please tell me where did I go wrong?

EDIT: I am using fragment creation using the template generated by Android Plug-in eclipse IDE. So the fragments are created using android.support.v4.app.Fragment

@Override
    public Fragment getItem(int position) {
        Fragment fragment = null;
        switch(position)
        {
        case 0:
            return new Frag1();
        case 1: 
            return new Frag2();
        }
        return fragment;
    }

The codebase is kept here for reference https://skydrive.live.com/redir?resid=D37E0F56FEC9B499!259

Kris
  • 640
  • 1
  • 11
  • 28

5 Answers5

24

Try This it works for me How to put Google Maps V2 on a Fragment Using ViewPager

<fragment
            android:id="@+id/map"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            class="com.google.android.gms.maps.SupportMapFragment" />

GoogleMap mGoogleMap = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map)).getMap();
Community
  • 1
  • 1
abozaid
  • 967
  • 8
  • 11
  • 2
    For me using getChildFragmentManger() was the fix. I was attempting to retrieve fragments from a fragment i.e. the fragments were children of the fragment where I was calling findFragmentById() – AlanKley Sep 20 '16 at 19:45
19

You should have added the fragment Frag2 by calling

getSupportFragmentManager().beginTransaction().add(R.id.frag2_view, new Frag2(), "tag").commit();

at your MainActivity, where R.id.frag2_view is a layout defined in your main_layout.

To get that Fragment, you should then call

Frag2 obj = (Frag2)getSupportFragmentManager().findFragmentById(R.id.frag2_view);

passing the layout id you used to add the fragment in the main_layout.

Hope it helps.

EDIT:

Since you use a ViewPager, you should use R.id.pager as the ID. I just tried with your example and it worked.

Frag2 fragmentObj=(Frag2) getSupportFragmentManager().findFragmentById(R.id.pager);

EDIT 2:

Despite it worked, I don't really think this is the correct way, since R.id.pager its from ViewPager and you can't find, let's say, frag4 or frag5.

Ignore my answer please. I'm not sure how to do that with ViewPager, sorry.

krishwader
  • 11,341
  • 1
  • 34
  • 51
Eduardo Herzer
  • 2,033
  • 21
  • 24
  • I am using **Fragment getItem** to put the fragments. So how should i apply your approach? I'm new to android(just 3 days old) :) – Kris Mar 20 '13 at 16:29
  • @Kris I just updated my answer based on your question update. I didn't know you were using ViewPager. Let me know if it works. – Eduardo Herzer Mar 20 '13 at 16:54
  • After the second edit I have unmarked the answer but I feel its useful. I will try to find an alternative approach/wait for the correct method .. – Kris Mar 20 '13 at 18:00
  • 4
    Check out this answer [link](http://stackoverflow.com/a/8886019/2174489). He uses `Frag2 fragmentObj=(Frag2) mSectionsPagerAdapter.instantiateItem(mViewPager, 1);` which seems to work – Eduardo Herzer Mar 20 '13 at 18:11
  • thanks for the help @Eduardo Herzer I have updated the answer with your last comment.(has to be peer reviewed.. :)) – Kris Mar 20 '13 at 18:57
7

I was having a similar problem and here is the solution. To get the reference to the proper fragment inside the viewpager just call:

getSupportFragmentManager().findFragmentByTag(tag);  

The tag param you can build it using the following syntax: "android:switcher:pager_id:index", where pager_id is the id of the ViewPager in the XML layout and the index is the position of your fragment inside the ViewPager starting by zero. See the original response here: https://stackoverflow.com/a/7393477/2423274

Community
  • 1
  • 1
Alejandro Casanova
  • 3,633
  • 4
  • 31
  • 46
5

Found the right solution for this question.

Hope more people see this.

Frag2 fragmentObj=(Frag2) mSectionsPagerAdapter.getItem(2);

You should use your Adapter (where you populate your fragments) as a source for get the Fragment reference.

Canato
  • 3,598
  • 5
  • 33
  • 57
0

I used this to get a child fragment from a fragment adapter...

Fragment parent = MainActivity.this.getSupportFragmentManager().findFragmentById(R.id.main_container);
        if (parent instanceof PagerFragment) {
            // do something with parent
            Fragment child = ((PagerFragment) f).adapter.getItem(childPosition);
        }
dianakarenms
  • 2,609
  • 1
  • 22
  • 22