Two activities using the same fragment. The fragment has a text view. Main activity writes “message 1” into the text view and it shows up.
A button in the main activity launches the second activity “for result”.
The Second activity writes “message 2” into the text view and it shows up.
A button in the second activity does set Result Activity.RESULT_OK and then finish().
The main activity gets the “onActivityResult” Result OK and writes “message 3” into the text view. However “Message 3” does not show up in the text view. Instead “message 1” shows up.
public class MainActivity extends AppCompatActivity {
private static Context context;
private static Button btn_main;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
btn_main = findViewById(R.id.btn_main);
FragmentDisplay.setMessage1("Message 1");
btn_main.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
secondactivityLauncher.launch(intent);
}
});
}
ActivityResultLauncher<Intent> secondactivityLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) {
FragmentDisplay.setMessage1("Message 3");
}
}
});
public static Context getContext(){
return context;
}
}
public class SecondActivity extends AppCompatActivity {
private static Button btn_second;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
btn_second = findViewById(R.id.btn_second);
FragmentDisplay.setMessage1("Message 2");
btn_second.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = getIntent();
setResult(Activity.RESULT_OK, intent);
finish();
}
});
}
}
public class FragmentDisplay extends androidx.fragment.app.Fragment {
private static TextView textView1;
public FragmentDisplay() {
// Required empty public constructor
}
RecyclerView mRecyclerView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.display_fragment, null);
textView1 = (TextView)view.findViewById(R.id.tv1);
return view;
}
public static void setMessage1(String str){
textView1.setText(str);
}
} // end of class
//activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".main.MainActivity">
<fragment
android:id="@+id/display_fragment"
android:name="ddi.pos.display.FragmentDisplay"
android:layout_width="700dp"
android:layout_height="180dp"
android:background="#00CC00"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginTop="80dp" />
<Button
android:id="@+id/btn_main"
android:layout_below="@+id/display_fragment"
android:layout_marginTop="100dp"
android:layout_marginLeft="50dp"
android:layout_width="200dp"
android:layout_height="200dp"
android:background="#FFFFFF00"
android:textSize="25sp"
android:text="Start Second Activity"
/>
//second_activity.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".main.MainActivity">
<fragment
android:id="@+id/display_fragment"
android:name="ddi.pos.display.FragmentDisplay"
android:layout_width="700dp"
android:layout_height="180dp"
android:background="#00CC00"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginTop="80dp" />
<Button
android:id="@+id/btn_second"
android:layout_below="@+id/display_fragment"
android:layout_marginTop="100dp"
android:layout_marginLeft="300dp"
android:layout_width="200dp"
android:layout_height="200dp"
android:background="#000000"
android:textSize="25sp"
android:text="Finish Second Activity"
/>
//display_fragment.xml
<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:background="#CC5500"
>
<TextView android:id="@+id/tv1"
android:background="#0055FF"
android:layout_height="60dp"
android:layout_width="600dp"
android:text=""
android:layout_marginLeft="30dp"
android:layout_marginTop="30dp"
android:textSize="20dp"
android:textColor="#ff000000"
/>
Caveat: I suspect that what you posted is not what you actually want to do, but a workaround of some kind so this answer may or may not actually address your use-case. It does, however, produce the behavior you asked for in the question. You said you are not trying to send data between activities, but you want the message in the first activity to change in response to actions in the second activity which implies information may be shared.
Main Answer: The example below, using a shared ViewModel between Activity and Fragment and using data transfer across activities using intents has the behavior you describe in your question.
The ViewModel allows sharing of data between the Activity and Fragment, since the Fragment can observe the LiveData and respond when the activity changes it. Since the question calls startActivityForResult
and handles the result, I used those to handle passing data back to change the message.
MainActivity.java
public class MainActivity extends AppCompatActivity {
ActivityResultLauncher<Intent> secondActivityLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) {
// as you indicated:
//viewModel.setMessage("Message 3");
// or like this if you sent data
Intent data = result.getData();
if( data != null ) {
Bundle extras = data.getExtras();
if( extras != null ) {
String msg = extras.getString("response");
viewModel.setMessage(msg);
}
}
}
}
});
private MainViewModel viewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewModel = new ViewModelProvider(this).get(MainViewModel.class);
// Always initialize the message to "Message 1"
viewModel.setMessage("Message 1");
Button btn = findViewById(R.id.btn_main);
btn.setOnClickListener(view -> {
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtra("message", "Message 2");
secondActivityLauncher.launch(intent);
});
}
}
SecondActivity.java
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
// This ViewModel instance is "not" the same instance as the one from MainActivity, it is
// just to facilitate communication between the Activity and Fragment
MainViewModel viewModel = new ViewModelProvider(this).get(MainViewModel.class);
// as you had it with hard-coded message 2
// viewModel.setMessage("Message 2");
// or like this if you sent the message
Intent i = getIntent();
Bundle b = i.getExtras();
if( b != null ) {
String msg = b.getString("message");
viewModel.setMessage(msg);
}
Button btn = findViewById(R.id.btn_second);
btn.setOnClickListener(view -> {
Intent intent = new Intent();
intent.putExtra("response", "Message 3");
setResult(Activity.RESULT_OK, intent);
finish();
});
}
}
MainViewModel.java
public class MainViewModel extends ViewModel {
private final MutableLiveData<String> message_to_display = new MutableLiveData<>();
LiveData<String> message() { return message_to_display; }
void setMessage(String msg) {
message_to_display.postValue(msg);
}
}
DisplayFragment.java
public class DisplayFragment extends Fragment {
public DisplayFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_display, container, false);
}
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
TextView txt = view.findViewById(R.id.tv1);
// Get the ViewModel from the hosting activity, could be
// Main or Second, and observe its message. Update the
// TextView if the message is changed.
MainViewModel viewModel = new ViewModelProvider(requireActivity()).get(MainViewModel.class);
viewModel.message().observe(getViewLifecycleOwner(), s -> {
txt.setText(s);
});
}
}