0

In my Fragemt.java there is something like this:

public class MainFragment extends Fragment implements View.OnClickListener {
    private TextView mTitleTextView;
    [...] irrelevant code cut out

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);
        [...] some other code

        mTitleTextView = (TextView) rootView.findViewById(R.id.titleTextView);
        mTitleTextView.setText("Text I Want to Set"); // Problem! App crashes on start if TextView isn't part of the fragment
        [...] more irrelevant code

And this is working fine now. After the App always crashed on loading and I was searching for hours. The problem was that the TextView (R.id.titleTextView) was located in the XML of the parent activity, not the xml assigned to the fragment.

Is there a way I could have changed the text of the parents TextView from inside the fragments java code?

EDIT logcat info

10-31 11:10:16.992 3259-3259/? E/AndroidRuntime: FATAL EXCEPTION: main
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime: Process: com.example.sebastian.recyclerlist, PID: 3259
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.sebastian.recyclerlist/com.example.sebastian.recyclerlist.MainActivity}: android.view.InflateException: Binary XML file line #20: Error inflating class fragment
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.app.ActivityThread.access$800(ActivityThread.java:151)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:102)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:135)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5254)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Native Method)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:372)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:  Caused by: android.view.InflateException: Binary XML file line #20: Error inflating class fragment
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:763)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:257)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at com.example.sebastian.recyclerlist.MainActivity.onCreate(MainActivity.java:38)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.app.Activity.performCreate(Activity.java:5990)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.app.ActivityThread.access$800(ActivityThread.java:151) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:102) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:135) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5254) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Native Method) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:372) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:  Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at com.example.sebastian.recyclerlist.MainActivity.setText(MainActivity.java:49)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at com.example.sebastian.recyclerlist.MainFragment.updateList(MainFragment.java:160)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at com.example.sebastian.recyclerlist.MainFragment.onCreateView(MainFragment.java:107)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.support.v4.app.Fragment.performCreateView(Fragment.java:1965)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1047)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1237)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1339)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2295)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.support.v4.app.FragmentController.onCreateView(FragmentController.java:111)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.support.v4.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:314)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.support.v4.app.BaseFragmentActivityHoneycomb.onCreateView(BaseFragmentActivityHoneycomb.java:31)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:79)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:733)
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.view.LayoutInflater.rInflate(LayoutInflater.java:806) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.view.LayoutInflater.inflate(LayoutInflater.java:504) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.view.LayoutInflater.inflate(LayoutInflater.java:414) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.view.LayoutInflater.inflate(LayoutInflater.java:365) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:257) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at com.example.sebastian.recyclerlist.MainActivity.onCreate(MainActivity.java:38) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.app.Activity.performCreate(Activity.java:5990) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.app.ActivityThread.access$800(ActivityThread.java:151) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:102) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:135) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5254) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Native Method) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:372) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 
10-31 11:10:16.992 3259-3259/? E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 
sbstnzmr
  • 401
  • 7
  • 21

2 Answers2

5

You can change the text in the TextView of the Activity hosting the Fragment with an interface. This answer is adapted from here.

public class BlankFragment extends Fragment implements View.OnClickListener{

    private View rootView;
    private EditText editText;
    private Button button;

    private OnFragmentInteractionListener mListener;

    //Your Activity will implement this interface
    public interface OnFragmentInteractionListener {
        void onFragmentInteraction(String message);
    }


    public static BlankFragment newInstance() {
        return new BlankFragment();
    }

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

Called from inside an onClick(), or wherever else, inside your Fragment:

public void onButtonPressed(String message) {
    if (mListener != null) {
        mListener.onFragmentInteraction(message);
    }
}

An example of how your Activity may look:

public class MainActivity extends AppCompatActivity implements BlankFragment.OnFragmentInteractionListener{

    private TextView mTextView;

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

        mTextView = (TextView) findViewById(R.id.text_view_id);

        if (getFragmentManager().findFragmentById(R.id.fragment_container) == null) {
            getFragmentManager()
                    .beginTransaction()
                    .add(R.id.fragment_container, BlankFragment.newInstance())
                    .commit();
        }
    }

    @Override
    public void onFragmentInteraction(String message) {
        mTextView.setText(String message);
    }
}

Edit: I should also mention an alternative method, where you set the TextView field to public in the hosting Activity and set it from your Fragment by casting getActivity() to the appropriate type:

((MainActivity)getActivity()).mTextView.setText("Text to set");

This is "easier" in the sense that it takes less typing, but I wouldn't ever recommend it as it tightly couples the Fragment to its Activity.

Community
  • 1
  • 1
PPartisan
  • 8,173
  • 4
  • 29
  • 48
0

@PPartisan's answer is good. However I would rather personally prefer a bit change in that pattern.

In my opinion, It's better to the Activity implements the interface not the fragment. In other words, suppose we have got multiple fragments tend to be attached to this activity at some point. Therefore, having each fragment its own interface doesn't seem so good.

My Solution

  • Declare a Java interface called for example, IParentActivity.
  • Get your main activity to implement this interface.
  • Implement necessary methods of the interface in your activity class.
  • Whenever a fragments wants to communicate with the activity. it should does something like this:

    IParentActivity parent = (IParentActivity) getActivity();
    parent.someMethod();
    
frogatto
  • 28,539
  • 11
  • 83
  • 129
  • This still crashes my app. The interface has only a `setText(String text)` method which in the MainActivity sets the `textView.setText(text);` Then in the fragment I have `IParentActivity parent = (IParentActivity) getActivity();` and `parent.setText("some Text`. The last statement is what crashes the app. – sbstnzmr Oct 31 '15 at 11:13
  • @sezi80 Did your activity implement the interface? BTW, post your logcat once you encounter a crash. – frogatto Oct 31 '15 at 12:04
  • @abbforce `public class MainActivity extends AppCompatActivity implements IParentActivity{`. I added the logcat info to the initial post. – sbstnzmr Oct 31 '15 at 15:41
  • @sezi80 Yes, it's correct. So, post the logcat for the crash. – frogatto Oct 31 '15 at 15:42
  • @abbforce I did add the logcat in my initial post. Thanks for your patience. – sbstnzmr Nov 01 '15 at 08:50
  • @sezi80 You've got a Null Pointer Exception at line 49 of `MainActivity.java` class. Please post those codes. – frogatto Nov 01 '15 at 09:24
  • It's the `titleTextView.setText("...")` of the override method from the interface. Same problem I got from the beginning when it still was in the fragment. I did a `tileTextView = (TextView) findViewById(R.id.titleTextView);"` in `onCreate` and the TextView is declared in the class so it is accessible by the other method. – sbstnzmr Nov 01 '15 at 17:44
  • @sezi80 So, make sure `titleTextView` is not null. – frogatto Nov 01 '15 at 18:41
  • How? I assing it in `onCreate` as always `tileTextView = (TextView) findViewById(R.id.titleTextView);`. Before that I set the layout `setContentView(R.layout.activity_main);` and in the layout there is a `TextView` with `android:id="@+id/titleTextView"`. It usually works fine just like this. Only not if I want to change something from within another fragment. – sbstnzmr Nov 02 '15 at 19:47
  • @sezi80 Due to lack of a comprehensive information, I cannot answer you in details. You may want to send me your whole project and I'll then fix it and send it back to you. If you would want, send it to the E-Mail address written in my profile. I'll respond you on Thu, 5th November. (Since I've got a midterm exam then!) – frogatto Nov 02 '15 at 20:21
  • I just wrote a new small app where there is nothing than the essentials. And it works! So technically I think your solution is correct. However doing the same in my app doesn't seem to work. Since it will work with nothing else around there is probably another problem. Unfortunately it is still the `textView.setText(text);` that crashes the app so still everything points to it not working there. Anyways thanks for your help. You still solved my initial problem. I'll figure thre rest out somehow. And good luck with your exam! – sbstnzmr Nov 03 '15 at 20:36
  • @abbforce just one more question. Why the interface? It does work without it. – sbstnzmr Nov 04 '15 at 19:46
  • @sezi80 Yes, I know. It does work but it also _does_ break software engineering principles. Did you pass [Software Engineering](https://en.wikipedia.org/wiki/Software_engineering) course? – frogatto Nov 04 '15 at 20:52