19

I have an activity which does a fragment transaction

DetailFragment newFragment = new DetailFragment();
transaction.replace(R.id.mylist, newFragment);
transaction.addToBackStack(null);
transaction.commit();

that works fine. Now I know within my activity a dynamic string I need to replace in the layout I have in newFragment. I thought that I can call after transaction.commit() just something like

newFragment.setMyString("my dynamic value");

And in the newFragment.java I have

public void setMyString(String s)
{
 TextView tv = (TextView) getActivity().findViewById(R.id.myobject);
 tv.setText(s);
}

The point is that getActivity() returns null. How can I get the context I need to find my layout elements?

Edit:

I try to follow the route using a bundle as this seems to be the cleanest way. So I have changed my code:

Bundle b = new Bundle();
b.putString("text", "my dynamic Text");
DetailFragment newFragment = new DetailFragment();
transaction.replace(R.id.mylist, newFragment);
transaction.addToBackStack(null);
transaction.commit();

My fragment onCreateView looks like this:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
{
   View v = inflater.inflate(R.layout.mylayout, container, false);
   TextView t = (TextView) v.findViewById(R.id.texttobereplaced);
   t.setText(savedInstanceState.getString("text");
}

It seems that savedInstranceState is empty. Where should I find my bundle?

Edit2:

missed the getArguments() in the reply. is working now.

AndyAndroid
  • 4,039
  • 14
  • 44
  • 71

4 Answers4

20

Make sure you call getActivity() in or after onAttach(), as before then it will return null.

Alex Lockwood
  • 83,063
  • 39
  • 206
  • 250
  • sorry I don't understand where I shall call getActivity() and pass it to my setMyString() function. And if I do it where you suggest you still write it may or may not return null. How shall I understand this? – AndyAndroid Jul 31 '12 at 18:05
  • 6
    The `Fragment` will be attached to a `null` activity until `onActivityCreated`... that is, if you call `getActivity()` in `onCreate` or `onCreateView`, it will return `null` because the `Activity` hasn't been created yet. So make sure you have all of your calls to `getActivity()` *in or after* `onActivityCreated`. – Alex Lockwood Jul 31 '12 at 18:12
  • 4
    This is wrong. Once onAttach is called getActivity() can be called without it returning null. onActivityCreated is just a callback for when the activity was fully created and the fragment's layout has been instantiated. – dymmeh Apr 03 '14 at 15:35
  • 2
    @AlexLockwood Why do you state it will return null in onCreate()? I see plenty of examples in Android framework where they call getActivity() inside of onCreate(). Here is one example: http://androidxref.com/4.4.3_r1.1/xref/packages/apps/Calendar/src/com/android/calendar/QuickResponseSettings.java – IgorGanapolsky Jul 10 '14 at 18:26
  • 2
    Yeah, I'm not sure why I wrote that... the activity should be available as long as you call `getActivity()` after `onAttach()`. I edited my original response to address this... and to be honest, I'm not sure how this answer got 5 upvotes. I guess I was more of a noob 2 years back. :P – Alex Lockwood Jul 11 '14 at 05:12
18

Your Fragment hasn't attached to the Activity yet, which also means your layout hasn't been inflated yet (See the Fragment lifecycle). The best solution here would be to add your String value as an argument to the Fragment via the Fragment.setArguments(Bundle) method. This can be retrieved in the receiving Fragment via the Fragment.getArguments() method.

Jason Robinson
  • 31,005
  • 19
  • 77
  • 131
2

So i am also using the same fragment transaction manager and the only problem i can see with your code is that you define the TextView tv inside your onCreateView method of your newFragment class and then instantiate it as like this :

public class AboutFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.newFragment, container, false);
        TextView tv = (TextView) v.findViewById(R.id.textview);
        return v;
    }

    public void setMyString(String s) {
        tv.setText(s);
    }
}

I know it does'nt make really much sense but that is how i am running my code and it works fine :)

Alex Lockwood
  • 83,063
  • 39
  • 206
  • 250
Android2390
  • 1,150
  • 12
  • 21
  • sorry did'nt know it was that important :) changed it ..hopefully looks better now – Android2390 Jul 31 '12 at 15:38
  • 3
    Of course indenting your code is important on StackOverflow... people aren't going to think you are a very credible source if your code is blatantly unreadable. I just edited your answer and removed the downvote. – Alex Lockwood Jul 31 '12 at 15:43
0

if u need to call getActivity in OnCreateView, move all ur code from onCreateView to onActivityCreate and only left lines

View v = inflater.inflate(R.layout.xxxx, container, false);
    return v;

in onCreateView

but i have a funny situation.

in My onActivityCreated

Spinner s1 = (Spinner) getActivity().findViewById(R.id.bitlength);
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
            getActivity(), R.array.bitlengths,
            android.R.layout.simple_spinner_item);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    s1.setAdapter(adapter);

Sometime the onActivityCreated wont run (correctly!?) and hence the spinner s1 become empty.