【问题标题】:Pass custom objects to next activity in Xamarin Android将自定义对象传递给 Xamarin Android 中的下一个活动
【发布时间】:2014-05-06 08:03:27
【问题描述】:

我有一些自定义对象,例如 RootObjectForm,我想将它们传递给下一个活动。

这是RootObject的一个例子:

public class RootObject
{
    public Form Form { get; set; }
}

但是我怎样才能将RootObject 传递给带有Intent 的下一个活动并在下一个Activity 中得到它?在Form 中再次有多个带有Lists 的属性,我需要在下一个Activity 中访问一些属性。我的意图是这样调用的:

saveButton.Click += delegate {
    if(ValidateScreen()){
        SaveData();
        Intent intent = new Intent(this, typeof(MainActivity));
        Bundle b = new Bundle();
        b.PutSerializable("RootObject", RootObject);
        StartActivity(intent);
    }
};

【问题讨论】:

  • 你在实现ISerializable接口RootObject吗?并且还将对象而不是类名作为PutSerializable 中的第二个参数传递为RootObject obj=new RootObject();b.PutSerializable("RootObject", obj);。如需更多帮助,请参阅Pass object between activity
  • 不,我不是,我该如何实现,我尝试在RootObject 之后添加: ISerializable,但它在此上下文中不存在。

标签: c# android android-activity xamarin


【解决方案1】:

我知道这是一个老问题,但我认为我的回答可能会对某人有所帮助。 我所做的是我使用了 JSON.Net 包,您可以使用 Nuget Manager 安装它。通过使用 JSON,您可以在第一个活动中序列化您的对象,然后在第二个活动中反序列化。 我就是这样做的:

活动一

using Newtonsoft.Json;
...
void mBtnSignIn_Click(object sender,EventArgs e)
{
      User user = new User();
      user.Name = "John";
      user.Password = "password";

      Intent intent = new Intent(this,typeof(Activity2));
      intent.PutExtra("User",JsonConvert.SerializeObject(user));
      this.StartActivity(intent);
      this.Finish();

}

活动 2

using Newtonsoft.Json;
...
private User user;
protected override void OnCreate(Bundle savedInstanceState)
{
      base.OnCreate(savedInstanceState);

      SetContentView(Resource.Layout.Activity2);
      user = JsonConvert.DeserializeObject<User>(Intent.GetStringExtra("User"));
}

希望这会对某人有所帮助。

【讨论】:

  • 快速简单。谢谢。
【解决方案2】:

您可以这样做。你的类需要实现 Serializable 或 Parcelable。 在第一个活动中(您要从哪里发送):

final Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("my_class", your_object);
startActivity(intent);

然后在你的第二个活动中,你会这样做:

final Intent passedIntent = getIntent();
final YourClass my_class = (YourClass) passedIntent.getSerializableExtra("my_class");

还有另一种方法,使用 Bundles::

从您的类中创建一个 Bundle,例如:

public Bundle toBundle() {
    Bundle b = new Bundle();
    b.putString("SomeKey", "SomeValue");

    return b;
}

然后用 INTENT 传递这个包。现在你可以通过传递 bundle 来重新创建你的类对象

public CustomClass(Context _context, Bundle b) {
    context = _context;
    classMember = b.getString("SomeKey");
}

【讨论】:

    【解决方案3】:

    嗯,在我的情况下,我想传递的对象不知道 Android 或 IOS,不是那样的。所以实现(Java 版本的)ISerializableIParcelable 不是一种选择。

    所以,我所做的是采用 JSON(使用 Newtonsoft.Json NuGet 包)方法并使用扩展方法。

    public static class IntentExtension
    {
        public static Intent PutExtra<TExtra>(this Intent intent, string name, TExtra extra)
        { 
            var json = JsonConvert.SerializeObject(extra);
            intent.PutExtra(name, json);
            return intent;
        }
    
        public static TExtra GetExtra<TExtra>(this Intent intent, string name)
        {
            var json = intent.GetStringExtra(name);
            if (string.IsNullOrWhiteSpace(json))
            {
                return default(TExtra);
            }
    
            return JsonConvert.DeserializeObject<TExtra>(json);
        }
    }
    

    然后这样称呼它:

    // Put extra
    MyDto dto = ...; // Get from server or something
    StartActivity(new Intent(this, typeof(MyActivity)).PutExtra("MY_EXTRA", dto))
    
    // Get the extra back
    var myDto = Intent.GetExtra<MyDto>("MY_EXTRA");
    

    【讨论】:

      【解决方案4】:

      在 Xamarin Android 中获得活动之间有效交互的关键是获得两个活动之间的引用“连接”。

      这并不像人们期望的那样完成(通过构造函数参数传递数据)。而且由于框架负责实例化第二个活动,因此您甚至不会获得对它的引用。

      这是一个大问题(至少对我个人而言)。现在我可能会建议,大致如下:

      public static class NavigationBridge
      {
          public static Action<object> FinishedNavigating { get; set; }
      }
      
      public class Activity1
      {
          protected override void OnCreate(Bundle savedInstanceState)
          {
              base.OnCreate(savedInstanceState);
              SetContentView(Resource.Layout.Main);
      
              someButton.Click += (sender, args) => 
              {
                  NavigationBridge.FinishedNavigating = activity2 =>
                  {
                      Activity2 activity = (Activity2)activity2;
                      // Vuola, you now have a reference to the instance.
                      // Use this reference to set public properties in Activity2, 
                      // using data from *this* Activity1
                  };
                  var intent = new Intent(this, typeof(Activity2));
                  this.StartActivity(intent);
              };
          }
      }
      
      public class Activity2
      {
          protected override void OnCreate(Bundle savedInstanceState)
          {
              base.OnCreate(savedInstanceState);
              SetContentView(Resource.Layout.Main);
              if (NavigationBridge.FinishedNavigating != null)
              {
                  NavigationBridge.FinishedNavigating(this);
                  NavigationBridge.FinishedNavigating = null;
              }
          }
      }
      

      我认为没有任何简单的方法可以在任何地方避免静态,但这样一来,您将只需要 1,因为您在 FinishedNavigating 操作中定义了要执行的作业。

      【讨论】:

      • 我将使用此解决方案。螺丝 Parcelables。
      【解决方案5】:

      我使用了 Xamarin 的 forum 上建议的不同方法。

      解决方案是将需要发送到下一个 Activity 的对象公开,以便可以从应用程序中的任何位置访问它。

      public class RootObject
      {
          private RootObject()
          {
          }
      
          private static RootObject _instance;
          public static RootObject Instance
          {
              get
              {
                  if (_instance == null)
                  {
                      _instance = new RootObject();
                   }
                  return _instance;
              }
          }
      
          public Form Form { get; set; }
      }
      

      并且可以使用以下代码在任何地方访问该对象:

      Form myForm = RootObject.Instance.Form;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-12-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多