-2

I would like to do a pretty simple task:

I got an activity A and an activity B.

Activity A contains an object that I want to change from activity B.

I tried to do so with following code:

Intent intent = new Intent(this, A.class); 
FragmentManager fragmentManager = getSupportFragmentManager(); 
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();     
fragmentTransaction.replace(R.id.fragment_container, new LogFragment()); 
fragmentTransaction.commit(); 
startActivity(intent);

Explanation:

fragment_container is the object I would like to replace by LogFragment (thats a fragment, speaking names for the win ^^ ).

This code doesn't work because he tells me that he can't find "fragment_container".

I guess thats because I am still in activity B while the "fragment_container" is found in activity A.

Is there a way how I can still address "fragment_container" while beeing in activity B? Another possibility could be that I would overwrite the startActivity method to something like startActivity(intent, fragment).

Is this possible and if yes, which methods do I need to overwrite? (I got basic java knowlegde but sadly no experience with android programming.)

Thanks for any help.

Squonk
  • 48,735
  • 19
  • 103
  • 135
Nerethar
  • 327
  • 2
  • 16
  • You really wouldn't want to follow this pattern in Android development. An Activity determines what's visible on the screen -- and what "lives" in your application. And Activity that's not visible may not exist. Trying to modify something that may or may not exist is error-prone and will most likely crash soon. Instead, you need to work out where to hold this shared data -- if it's dynamic, consider a static singleton (google that), if it's fairly static, use SharedPreferences or a database. – 323go May 30 '14 at 14:42
  • **"Activity A contains an object that I want to change from activity B.**" : Don't ever try this directly. Your code will crash and burn. As others have said use a POJO helper, SharedPreferences or Intent extras. – Squonk May 30 '14 at 14:44
  • To clarify things: I actually know that the program structure is a mess, but there is unfortunatly to little time to fix that. So I needed a quickfix till the weekend. After that I will have to get rid of a lot of stuff in this code. – Nerethar May 30 '14 at 16:41

4 Answers4

0

I am not sure what exactly you want to do. That you try to perform a FragmentTransaction like that seems weird. If you explain more about what you want to achieve I can give you a more accurate answer.

Anyway you can pass data between Activities by adding it to the Intent. For example here I add the class of the Fragment you want to be displayed in Activity A to the Intent. The key "fragmentClass" is used to get the data back from the Intent in Activity A.

Intent intent = new Intent(this, A.class); 
intent.putExtra("fragmentClass", LogFragment.class);
startActivity(intent);

In Activity As onCreate():

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

    // savedInstanceState is null on the first Start of the Activity, as in when it was started with an Intent
    if(savedInstanceState == null) {

        // We get the Intent that started the Activity
        Intent intent = getIntent();

        // And retrieve the Class object we attached to the Intent with the key "fragmentClass".
        Class<?> fragmentClass = (Class<?>) intent.getSerializableExtra("fragmentClass");

        // Now we can instantiate the Fragment and perform the FragmentTransaction
        Fragment fragment = Fragment.instantiate(this, fragmentClass.getName());

        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.fragment_container, fragment);
        fragmentTransaction.commit();
    }
}

So by using this code you could start the Activity A with any Fragment you like, you just have to add the class of the Fragment you want to be displayed to the Intent as I showed above.

Xaver Kapeller
  • 49,491
  • 11
  • 98
  • 86
  • 1
    If you have no idea what the question is, how can you answer?? – 323go May 30 '14 at 14:40
  • @323go I know what he is asking, it is obvious, just read the question. I just don't know exactly what he wants to do, as in why he wants to perform a `FragmentTransaction` at all in that case. There is nothing wrong with my answer. It fixes his code, it explains what is happening, so why would you downvote this answer? – Xaver Kapeller May 30 '14 at 14:48
  • Thank you very much, this solved my problem. I don't know why people downvoted you. – Nerethar May 30 '14 at 16:39
0

I would not use Fragments for this task (unless you have a very good reason to do so).

What You can do to change the object in activity A from Activity B is to start the activity B from the activity A using the startActivityforResult method:

  //this is in activity A
  protected void startActivityB() {
       Intent i = new Intent(this, ActivityB.class);
       startActivityForResult(i, ACTIVITY_B);//ACTIVITY_B is a constant to identify B
  }

In the activity B, when you have done your stuff and you want to go back to activity A passing the Object:

  //this is in Activity B
  protected void goBackToActivityA() {
          Object myObjectToBePassedBack = ...;//whatever you have done/ or do to it
          Intent returnIntent = new Intent();
          returnIntent.putExtra("obj", myObjectToBePassedBack);
          setResult(RESULT_OK, returnIntent);
          finish();
  }

Then in activity A:

  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
     if (requestCode == ACTIVITY_B) {
        if (resultCode == RESULT_OK) {
            Object receivedBack = data.getExtra("obj");
            //Do what you want here with the object passed back
        }
     }
  }

Notice that the object must be serialisable to do this.

AMC
  • 130
  • 8
0

If you want all activities to have access to shared state then extend Application (see Extending Application to share variables globally)

Community
  • 1
  • 1
Mike Argyriou
  • 1,250
  • 2
  • 18
  • 30
0

Wait, so do you need to send objects between two Fragments, or two Activities? The way it's done is different.

If you're trying to send from activity to activity, you need to use the Extras section of the Intent. To place something in the Extras, it must implement the Parcelable interface.

Just throw your POJO class into this site, and it will have everything for Parcelling. http://www.parcelabler.com/

However, if you want to send it from one Fragment to another, then you should use the fragment.setBundle(bundle); function, and place the Parcellable into that.

I am not entirely sure what you're trying to do with the Fragments and Activities. I think you want to use 1 activity and 2 fragments in this case, rather than 2 activities and... one fragment that's shared between them, I think? I really am not sure.

EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
  • 1
    Fragments should never have direct communication with other fragments. – Squonk May 30 '14 at 14:41
  • Hmm. That's a valid point. In my code, I had a specific "container" Activity which could contain a single Fragment, and a ListFragment had the data. When the Data was selected, the ListFragment instantiated the Fragment, sent it to the Container Activity through a function call, and the Activity replaced the Fragment with the one that was given to it through the function call (and adding it to the backstack). Considering the ListFragment was responsible for knowing the particular selected data and the other Fragment depended on it, I ended up giving it that responsibility. Might be a bad idea. – EpicPandaForce May 30 '14 at 14:47
  • So it technically worked as the following: - ListFragment's OnListItemClick - instantiate "detailed" Fragment - set arguments for Fragment - send the Fragment to activity - replace current ListFragment with Fragment (add it to backstack) although I guess there would need to be logic to replace it in a different container if different layout is being supported, that is not much different from how the resolutions are handled. Is this a terrible idea? – EpicPandaForce May 30 '14 at 14:49
  • Yes, a bad idea. The idea of fragments is they should be modular (self-contained) and reusable. Only the Activity which creates fragments should "know" what they do. No fragment should ever know how another fragment works or even if any other fragment exists. All communication should be done from a fragment to the Activity and then the Activity handles communication to any other fragment if needed. – Squonk May 30 '14 at 14:51
  • Well, I guess I AM kinda new to Fragment-based Android programming. I wish I could show you exactly what I did, in order to make the activity only be a "fragment container" and be just a dumb instantiater and holder rather than the base of all logic. I might just make a question about it later, because I can't see its errors properly yet. – EpicPandaForce May 30 '14 at 15:02
  • To fix this problem, I created a parcellable fragment factory, and a specific fragment type holds a subclass of this - this is instantiated and sent to the activity from the fragment, and while I like it, I can't really tell if it's better or worse. :/ I think if it's done with local broadcasts rather than the function call I am initially doing, it'll make sense. There's a bit more code replication than I had hoped, though, so I'll figure out something about that. – EpicPandaForce Jun 02 '14 at 08:49