Reputation: 67
I have a MainActivity that immediately calls SetContentView(to the main screen). On button press, it starts a new intent activity1 that opens the second screen and transfers variables to it with PutExtra.
Now if I want to go back to the main screen on button press, Finish(); is a perfect way to do it because it stops activity1 and I am taken back to the main screen no problem.
Although, when I want to transfer variables back to the main screen, I have to create a new intent/activity that creates a completely new instance of the main screen.
Is there a way to pass data back from the second activity without creating a new instance of the main screen?
MainActivity.cs
using System;
using System.Collections.Generic;
using Android.App;
using Android.Content;
using Android.Provider;
using Android.Views;
using Android.Widget;
using Android.OS;
using static Android.Renderscripts.ScriptGroup;
using Android.Preferences;
namespace App11
{
[Activity(Label = "App11", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Android.App.Activity
{
//define all variables
IList<String> listitems = new List<String>();
public static int putposition;
public static string putname;
public static int getposition;
public static string getname;
bool edittoggle = false;
int count = 1;
protected override void OnCreate(Bundle bundle)
{
//create screen
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
ActionBar.Hide();
//get/define widgets from screen
TextView text_title = FindViewById<TextView>(Resource.Id.Text_Title);
ListView list_schedule = FindViewById<ListView>(Resource.Id.List_Schedule);
ImageButton buttonadditem = FindViewById<ImageButton>(Resource.Id.Button_AddItem);
ImageButton buttonedititem = FindViewById<ImageButton>(Resource.Id.Button_EditItem);
ImageButton buttonsettings = FindViewById<ImageButton>(Resource.Id.Button_Settings);
//define array
ArrayAdapter adapter = new ArrayAdapter<String>(this, Android.Resource.Layout.SimpleListItem1, listitems);
list_schedule.Adapter = adapter;
//on additem click
FindViewById<ImageButton>(Resource.Id.Button_AddItem).Click += delegate { adapter.Add("Alarm Item " + count++); };
//on edititem click
FindViewById<ImageButton>(Resource.Id.Button_EditItem).Click += delegate
{
//toggle
if (edittoggle == true)
{
edittoggle = false;
}
else
{
edittoggle = true;
}
};
//on list item click
list_schedule.ItemClick += (s, e) =>
{
//if edititem button is toggled on
if (edittoggle == true)
{
//create new intent activity1
Intent activity1 = new Intent(this, typeof(Activity1));
//put position of item from list
putname = (String)adapter.GetItem(e.Position);
activity1.PutExtra("Main_Put_Edit_Name", putname);
Console.WriteLine("put int edit name = " + putname);
//put name of item from list
putposition = e.Position;
activity1.PutExtra("Main_Put_Edit_Position", putposition);
Console.WriteLine("put string edit position = " + putposition);
StartActivityForResult(activity1, 0);
}
else
{
//TODO: show settings
}
};
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (resultCode == Result.Ok)
{
getname = data.GetStringExtra("Main_Put_Edit_Name2");
Console.WriteLine("get int edit name = " + getname);
getposition = data.GetIntExtra("Main_Put_Edit_Position2", 0);
Console.WriteLine("get int edit position = " + getposition);
//put_name and put_position should now hold the results you want, you can do whatever you want with these two values now in your MainActivity
Console.WriteLine("test = " + listitems[0]);
//but now range is out of bounds because listitems is only properly defined in OnCreate
}
}
}
}
}
Activity1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Provider;
using static Android.Renderscripts.ScriptGroup;
using Android.Preferences;
namespace App11
{
[Activity(Label = "Activity1")]
public class Activity1 : Android.App.Activity
{
//define variables
IList<string> listitems = new List<string>();
public static int get_position;
public static string get_name;
protected override void OnCreate(Bundle bundle)
{
//create screen
base.OnCreate(bundle);
SetContentView(Resource.Layout.layout1);
ActionBar.Hide();
//define screen widgets
ListView list_schedule2 = FindViewById<ListView>(Resource.Id.List_Schedule2);
EditText alarm_name = FindViewById<EditText>(Resource.Id.name_input);
Button donebutton = FindViewById<Button>(Resource.Id.button_done);
//get extras from activity1
get_position = Intent.GetIntExtra("Main_Put_Edit_Position", 0);
Console.WriteLine("get array edit position = " + get_position);
get_name = Intent.GetStringExtra("Main_Put_Edit_Name");
Console.WriteLine("get array edit name = " + get_name);
//just cuz
alarm_name.Text = get_name;
ArrayAdapter adapter = new ArrayAdapter<String>(this, Android.Resource.Layout.SimpleListItem1, listitems);
list_schedule2.Adapter = adapter;
FindViewById<Button>(Resource.Id.button_done).Click += delegate
{
//create new intent
Intent intent = new Intent(); //Added the type of Main Activity
int put_position = get_position;
intent.PutExtra("Main_Put_Edit_Position2", put_position);
Console.WriteLine("put array edit position = " + put_position);
string put_name = alarm_name.Text;
intent.PutExtra("Main_Put_Edit_Name2", put_name);
Console.WriteLine("put array edit name = " + put_name);
SetResult(Result.Ok, intent); //added the SetResult method.
Finish();
};
}
}
}
I'm just testing it with int and string right now. Put/Get the position(int) and name(string) of the list item.
Upvotes: 4
Views: 7089
Reputation: 1610
Implement OnActivityResult override inside the MainActivity.cs - in Xamarin, That's the only place it will fire. Even if you try the implement the override inside other activities, they are not going to work.
To get the result inside the activity of your choice, use a messaging centre implementation in your solution.
Upvotes: 0
Reputation: 4210
According to Xamarin Official Documentation there is a way to pass back data from second activity to the first one that launched it.
The key is to use StartActivityForResult
to launch the second activity from the first one, and use SetResult
in the second activity before the Finish()
method to send the results back to the first activity.
As you can see in the link I posted above, it's simple and straight forward to use.
You start your second activity from inside the first one using this code:
var myIntent = new Intent (this, typeof(SecondActivity));
StartActivityForResult (myIntent, 0);
In your second activity and when you want it to finish with a set of results, you can use this code:
Intent myIntent = new Intent (this, typeof(FirstActivity));
myIntent.PutExtra ("greeting", "Hello from the Second Activity!");
SetResult (Result.Ok, myIntent);
Finish();
In order to retrieve the results sent back to the first activity, you have to use this code:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (resultCode == Result.Ok) {
string stringRetFromResult = data.GetStringExtra("greeting");
//stringRetFromResult should hold now the value of 'Hello from the Second Activity!'
}
}
According to the code you have posted, I am assuming that you want to send the results back in this part of the code:
FindViewById<Button>(Resource.Id.button_done).Click += delegate
{
...
};
Try this one instead:
FindViewById<Button>(Resource.Id.button_done).Click += delegate
Intent intent = new Intent(this, typeof(MainActivity); //Added the type of Main Activity
int put_position = get_position;
intent.PutExtra("Main_Put_Edit_Position2", put_position);
Console.WriteLine("put array edit position = " + put_position);
string put_name = alarm_name.Text;
intent.PutExtra("Main_Put_Edit_Name2", put_name);
Console.WriteLine("put array edit name = " + put_name);
SetResult(Result.Ok, intent); //added the SetResult method.
Finish();
};
In addition to that, in your first activity, change StartActivity(activity1);
to StartActivityForResult(activity1, 0);
and you have to add this code to your Main Activity:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (resultCode == Result.Ok) {
string put_name = data.GetStringExtra("Main_Put_Edit_Name2");
int put_position = data.GetIntExtra("Main_Put_Edit_Position2");
//put_name and put_position should now hold the results you want, you can do whatever you want with these two values now in your MainActivity
}
}
Upvotes: 6