2

So I am still fairly new to working with Android Studio and everything in it. I have been stuck on trying to get fragments to communicate directly with each other. Here I'm simply just trying to set the TextView text element within one of my fragments. I have looked for hours and tried a lot, but I'm not sure what to do. Also, I am implementing my fragments through code in a FrameLayout.

Here is my fragment whose text value I'm trying to edit:

public class ReceivingFrag extends Fragment {

TextView sender;

public void updateText(String text) {
    sender.setText(text);
}

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.frag_sender, container, false);
    sender = (TextView) v.findViewById(R.id.sender);
    return v;
}

}

I believe my root problem is that getView() and sender both return Null. I also understand that fragments are not technically views, but rather aid in the layout of views and ViewGroups. Any help is appreciated.

Not sure if it helps, but this is the method that calls the updateText() method within the ReceivingFrag class.

public void sendText(String text){
    ReceivingFrag frag = new ReceivingFrag();
    getSupportFragmentManager().beginTransaction().add(R.id.receiving_container, frag).commit();
    getSupportFragmentManager().executePendingTransactions()
    frag.updateText(text);
}

**Edit: This is my MainActivity class that is calling and creating the Fragment:

public class MainActivity extends AppCompatActivity implements SendingFragment.TextClicked {

private static final String TAG = MainActivity.class.getSimpleName();

public final static String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE";
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    String[] myStringArray = {"Hello", "Nice To See You", "Bye"};

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
            android.R.layout.simple_list_item_1, myStringArray);

    ListView listView = (ListView) findViewById(R.id.mobile_list);
    listView.setAdapter(adapter);

    sendText("Hello");

}

@Override
public void sendText(String text){
     ReceivingFrag frag = new ReceivingFrag();
    getSupportFragmentManager().beginTransaction().add(R.id.receiving_container, frag).commit();
    getSupportFragmentManager().executePendingTransactions();
    frag.updateText(text);
}}

**Edit 2: This is the MainActivity layout file:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/apk/tools"
    xmlns:tools2="http://schemas.android.com/tools"
    android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:weightSum="1">

<EditText android:id="@+id/edit_message"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:hint="@string/edit_message"
    android:layout_weight="1" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="sendMessage"
    android:text="@string/button_send"/>

</LinearLayout>

<ListView android:id="@+id/mobile_list"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

<FrameLayout
    android:id="@+id/receiving_container"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"></FrameLayout></LinearLayout>

And this is the layout for the Fragment:

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

<TextView
    android:id="@+id/sender"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/frag_sender"
    android:background="@color/gray"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"/></LinearLayout>

Solution: So as mentioned below, the runtime error was fixed by adding

   @Override
protected void onResume() {
    super.onResume();
    sendText("hello");
}

to the MainActivity class. After reading from https://developer.android.com/guide/components/fragments.html#Lifecycle I think the statement

"Once the activity reaches the resumed state, you can freely add and remove fragments to the activity. Thus, only while the activity is in the resumed state can the lifecycle of a fragment change independently."

best explains the situation and why the error initially occurred.

Kobe M.
  • 40
  • 8

2 Answers2

0

Change your Fragment to this:

public class ReceivingFrag extends Fragment {

   private TextView sender;

   public void updateText(String text) {
      sender.setText(text);
   }

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

and in your activity, before calling the updateText method, make sure the fragment transaction has executed by doing:

public void sendText(String text){
   ReceivingFrag frag = new ReceivingFrag();
   getSupportFragmentManager().beginTransaction().add(R.id.receiving_container, frag).commit();
   getSupportFragmentManager().executePendingTransactions();
   frag.updateText(text);
}
Nilesh Singh
  • 1,750
  • 1
  • 18
  • 30
  • It would make sense for the error to occur if the fragment transaction hadn't executed, but this didn't help either as the `sender` is still null. – Kobe M. Jan 01 '17 at 00:27
  • I checked the code on my phone and adding getSupportFragmentManager().executePendingTransactions(); solves the issue. – Nilesh Singh Jan 01 '17 at 00:28
  • @KobeM.Also, would you please add Fragment's layout code? – Nilesh Singh Jan 01 '17 at 00:29
  • Of course! I added in the layout files for both classes above. – Kobe M. Jan 01 '17 at 00:43
  • Can you also update the code you've changed till now? – Nilesh Singh Jan 01 '17 at 00:43
  • I've updated the changes in the code above. The only areas that were affected were the `sendText()` method and the `ReceivingFrag` class. – Kobe M. Jan 01 '17 at 00:53
  • Have you checked using setText inside the onCreateView method, without updateText to check if the textView is correctly initialised on fragment creation. – Nilesh Singh Jan 01 '17 at 01:02
  • That actually worked! I got rid of the `updateText()` call and instead just called `setText()` from within the `onCreateView(...)` call. So why would it not work in the `updateText()` call then? Obviously the view is not null and `sender.setText()` works within `onCreateView(...)` method. – Kobe M. Jan 01 '17 at 01:12
  • Try changing extends Fragment to extends android.support.v4.app.Fragment in your Fragment. – Nilesh Singh Jan 01 '17 at 01:16
  • By extending Fragment it imported android.supportv4.app.Fragment already – Kobe M. Jan 01 '17 at 01:20
  • This is all I can help you with. The same code works for me with executePendingTransactions(); – Nilesh Singh Jan 01 '17 at 01:21
  • That's fine! I'll work with it some more! I appreciate the help! – Kobe M. Jan 01 '17 at 01:22
  • Please make sure you update the code once you get things right so that others can get benefited too. :) – Nilesh Singh Jan 01 '17 at 01:23
0

If you instead put the sendText() in your onResume() like this,

 @Override
protected void onResume() {
    super.onResume();

    sendText("Hello");

}

It will not give you the Null Pointer Exception. The fragment is still null when you call on it from onCreate().

Nick Friskel
  • 2,369
  • 2
  • 20
  • 33
  • Oh snap! That worked! Thanks! Can you explain the logic behind this? I am just a little confused on the state of the fragment at each call and where it changes specifically! I ended up removing the call of `sendText()` from the `onCreate()` method body and to the `onResume()' like you said. – Kobe M. Jan 01 '17 at 02:11
  • I believe it has to do with the specific order in which the fragment/activity methods are called, and when the view is returned in `onCreateView()`.. also `onResume()` begins the interaction with the user, not `onCreate()`. Honestly I don't 100% understand it and do not want to give you false info, but here is some reading I am checking out and i'll let you know if I find anything that 'clicks' with me.. https://developer.android.com/guide/components/fragments.html#Lifecycle http://stackoverflow.com/questions/28929637/difference-and-uses-of-oncreate-oncreateview-and-onactivitycreated-in-fra – Nick Friskel Jan 01 '17 at 02:17