3
votes

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.

2
hasnt worked for me the last 100 times but i will try again just to humor youDeathhound
humor me? You know that your question isn't even close to How to ask on SO? At least post what you have tried, and post your failed attempt, then you can get better results and better answers around here.Paul Karam
sorry i am beyond done with xamarin. Ive extensively researched new bundle, onsavedinstance, onactivityresult, etcetcetc and all i come across is outdated code or code that doesnt workDeathhound
Can you post the code you tried and failed you?Paul Karam

2 Answers

5
votes

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!'
    }
}

Update

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
    }
}
0
votes

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.