-1

I'm trying to send data from an activity to a fragment with argument.I know this question has been asked many time on SO but i can't seem to solve my problem.

I have seen the following thread that has the same problem:

Send data from activity to fragment in android

Transfer data from Fragment Activity to Fragment

and many other.

I've seen the Developer.android site too, I'vr tried the following code but I got a NPE:

MainActivity:

public class MainActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Fragment1.newInstance("from Activity");

    }

}

Fragment1:

public class Fragment1 extends Fragment {

    TextView tv;
    public static Fragment1 newInstance(String string) {
        Fragment1 frag = new Fragment1();
        Bundle args = new Bundle();
        args.putString("title", string);
        frag.setArguments(args);
        return frag;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View v = inflater.inflate(R.layout.fragment1_layout, container, false);
        tv = (TextView) v.findViewById(R.id.textView1); 
        tv.setText(getArguments().getString("title")); // line 27



        return v;
    }
}

activity_main:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

    <fragment       // line 17
        android:id="@+id/fragment1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignLeft="@+id/textView1"
        android:layout_below="@+id/textView1" 
        class="com.exam.simplefragmenttoturial.Fragment1"/>

</RelativeLayout>

fragment1_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/RelativeLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="Fragment 1" />

</RelativeLayout>

Logcat error:

03-04 10:29:43.657: E/AndroidRuntime(28453): FATAL EXCEPTION: main
03-04 10:29:43.657: E/AndroidRuntime(28453): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.exam.simplefragmenttoturial/com.exam.simplefragmenttoturial.MainActivity}: android.view.InflateException: Binary XML file line #17: Error inflating class fragment
03-04 10:29:43.657: E/AndroidRuntime(28453):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2266)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2316)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at android.app.ActivityThread.access$600(ActivityThread.java:150)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1298)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at android.os.Handler.dispatchMessage(Handler.java:99)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at android.os.Looper.loop(Looper.java:213)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at android.app.ActivityThread.main(ActivityThread.java:5225)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at java.lang.reflect.Method.invokeNative(Native Method)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at java.lang.reflect.Method.invoke(Method.java:525)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:741)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at dalvik.system.NativeStart.main(Native Method)
03-04 10:29:43.657: E/AndroidRuntime(28453): Caused by: android.view.InflateException: Binary XML file line #17: Error inflating class fragment
03-04 10:29:43.657: E/AndroidRuntime(28453):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:713)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:274)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at android.app.Activity.setContentView(Activity.java:1895)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at com.exam.simplefragmenttoturial.MainActivity.onCreate(MainActivity.java:13)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at android.app.Activity.performCreate(Activity.java:5133)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2230)
03-04 10:29:43.657: E/AndroidRuntime(28453):    ... 11 more
03-04 10:29:43.657: E/AndroidRuntime(28453): Caused by: java.lang.NullPointerException
03-04 10:29:43.657: E/AndroidRuntime(28453):    at com.exam.simplefragmenttoturial.Fragment1.onCreateView(Fragment1.java:27)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at android.support.v4.app.Fragment.performCreateView(Fragment.java:1478)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:900)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1082)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1184)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:285)
03-04 10:29:43.657: E/AndroidRuntime(28453):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:685)
03-04 10:29:43.657: E/AndroidRuntime(28453):    ... 21 more

Because I got a NPE on line 27 that I've indicate on the Fragment class, so I believe there are 2 possible causes.

1- tv is null, but I've tested it with following line and it worked:

tv.setText("test");

2- getArgument() is null, and I don't know how I can resolve that.

I think onCreateView is called before passing data to the fragment, so I got an NPE because I haven't set anything and the argument is null. I can send data from the activity with static method but I want to send data with the argument. Any help will be appreciated.

EDIT

this is all my code, i don't have anything else.

UPDATE

this is changed that i made based on Raghunandan's say:

Fragment1:

public class Fragment1 extends Fragment {

    TextView tv;
    public static Fragment1 newInstance(String string) {
        Fragment1 frag = new Fragment1();
        Bundle args = new Bundle();
        args.putString("title", string);
        frag.setArguments(args);
        return frag;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        View v = inflater.inflate(R.layout.fragment1_layout, container, false);
        tv = (TextView) v.findViewById(R.id.textView1); 
        tv.setText(getArguments().getString("key")); // this is line 27



        return v;
    }

MainActivity:

public class MainActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Bundle bundle = new Bundle();
        bundle.putString("key", "From Activity");
        Fragment1 fragobj = new Fragment1();
        fragobj.setArguments(bundle);



    }

}
Community
  • 1
  • 1
  • check this http://stackoverflow.com/questions/12739909/send-data-from-activity-to-fragment-in-android – Raghunandan Mar 04 '14 at 07:40
  • @Raghunandan i used like that, but i think `onCreateView` called before `Fragment1.newInstance("from Activity");` because i set class in `xml` and i think that called on `setContentView` –  Mar 04 '14 at 07:42
  • i see you have already have a fragment declared in xml. can you log the value of the string in newInstance??. yes onCreateView is called when the fragment is created. No you have not used like that – Raghunandan Mar 04 '14 at 07:44
  • @Raghunandan i call that method on `MainActivity` and value of that is `from Activity`. –  Mar 04 '14 at 07:45
  • try the suggestion in my post – Raghunandan Mar 04 '14 at 07:48

3 Answers3

1

You need

Bundle bundle = new Bundle();
bundle.putString("key", "From Activity");
Fragment1 fragobj = new Fragment1();
fragobj.setArguments(bundle);

in Activity

Then in onCreateView

tv.setText(getArguments().getString("key"));

In activity_main.xml have

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/container">
</FrameLayout>

Then in MainActivtiy

Fragment1 fragobj = new Fragment1();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.container, fragobj);
transaction.addToBackStack(null);
transaction.commit();
Bundle bundle = new Bundle();
bundle.putString("key", "From Activity");
fragobj.setArguments(bundle);

Then in Fragment

  View v = inflater.inflate(R.layout.fragment1_layout, container, false);
  tv = (TextView) v.findViewById(R.id.textView1); 
  tv.setText(getArguments().getString("key"));

Snap

enter image description here

Raghunandan
  • 132,755
  • 26
  • 225
  • 256
0

You can always get whatever you need from Activity by (MainActivity)getActivity().getWhatever() anywhere in your fragment. This is very common pattern and I recommend you to use it unless you have multiple different activities sharing your fragment.

If however you prefer to left your code as is, I suggest that you should call super.onCreateView() before trying to get arguments.

UPDATE: Instead of

<fragment       // line 17
        android:id="@+id/fragment1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignLeft="@+id/textView1"
        android:layout_below="@+id/textView1" 
        class="com.exam.simplefragmenttoturial.Fragment1"/>

Put an empty FrameLayout here with the same id. Then, from your Activity:

        Fragment f = Fragment1.newInstance("from Activity");
        getFragmentManager().beginTransaction()
                .add(R.id.fragment1, f).commit();
Dmide
  • 6,422
  • 3
  • 24
  • 31
  • thanks for your reply, i know that way is worked, i can send with static method too, but i want to send data with argument. `super.onCreateView()` not solved my problem –  Mar 04 '14 at 07:39
  • Can you provide a code where you're calling `FragmentManager` to add fragment? Also, it is better to use String constant instead of plain string "title". – Dmide Mar 04 '14 at 07:50
  • yes, i know, but it's one sample. this is all my code. –  Mar 04 '14 at 07:54
  • you mean you don't use a FragmentManager? You should do this. From your activity: `getFragmentManager().beginTransaction().add(R.id.where_to_put_fragment,fragment).commit();` – Dmide Mar 04 '14 at 07:57
  • i add fragment on `xml` file, i don't think so this need, any way i got `NPE` on `setContentView()` –  Mar 04 '14 at 08:02
  • You see, when a fragment is declared in xml it is instantiated by the system and therefore there's no data in this instance. To get your data you should inflate your fragment manually using the code I provided. – Dmide Mar 04 '14 at 08:05
  • Are You Sure About That?vow, and how can add one fragment in one position of my layout? –  Mar 04 '14 at 08:07
0

In your activity layout, you should use FrameLayout instead of "fragment". Then you can set your fragment on it like this:

Fragment1 newFragment = Fragment1.newInstance(); 
getSupportFragmentManager().replace(R.id.id_of_frame_layout, newFragment).commit();

Be sure that your FragmentActivity and your Fragment are both from the support library.

Daniel Zolnai
  • 16,487
  • 7
  • 59
  • 71
  • I got `The method replace(int, Fragment1) is undefined for the type FragmentManager` –  Mar 04 '14 at 08:11