Xamarin Android C#:如何在没有新意图的情况下从活动传回数据

Dea*_*und 3 c# android android-intent android-activity xamarin

我有一个立即调用 SetContentView(到主屏幕)的 MainActivity。按下按钮时,它会启动一个新的意图活动1,打开第二个屏幕并使用 PutExtra 将变量传输给它。

现在,如果我想在按下按钮时返回主屏幕,Finish(); 是一种完美的方法,因为它会停止活动 1 并且我被带回主屏幕没问题。

虽然,当我想将变量传输回主屏幕时,我必须创建一个新的意图/活动来创建一个全新的主屏幕实例。

有没有办法在不创建主屏幕的新实例的情况下从第二个活动传回数据?

主Activity.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
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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();
            };
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我现在只是用 int 和 string 测试它。放置/获取列表项的位置(整数)和名称(字符串)。

Pau*_*ram 5

根据Xamarin 官方文档,有一种方法可以将数据从第二个活动传递回启动它的第一个活动。

关键是使用StartActivityForResult从第一个活动启动第二个活动,并SetResult在第二个活动中使用之前的Finish()方法将结果发送回第一个活动。

正如您在我上面发布的链接中看到的那样,它使用起来简单直接。

您可以使用以下代码从第一个活动内部开始您的第二个活动:

var myIntent = new Intent (this, typeof(SecondActivity));
StartActivityForResult (myIntent, 0);
Run Code Online (Sandbox Code Playgroud)

在您的第二个活动中,当您希望它以一组结果结束时,您可以使用以下代码:

Intent myIntent = new Intent (this, typeof(FirstActivity));
myIntent.PutExtra ("greeting", "Hello from the Second Activity!");
SetResult (Result.Ok, myIntent);
Finish();
Run Code Online (Sandbox Code Playgroud)

为了检索发送回第一个活动的结果,您必须使用以下代码:

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!'
    }
}
Run Code Online (Sandbox Code Playgroud)

更新

根据您发布的代码,我假设您想在代码的这一部分将结果发回:

FindViewById<Button>(Resource.Id.button_done).Click += delegate
{
    ...
};
Run Code Online (Sandbox Code Playgroud)

试试这个:

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();
};
Run Code Online (Sandbox Code Playgroud)

除此之外,在您的第一个活动中,更改StartActivity(activity1);StartActivityForResult(activity1, 0);并且您必须将此代码添加到您的主活动中:

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
    }
}
Run Code Online (Sandbox Code Playgroud)