Xamarin表单PushAsync打开一个空白页面

时间:2017-06-12 15:51:56

标签: android xamarin xamarin.forms navigation

我目前正在开展一个项目,我在设备上收到了推送通知,在点击通知时,它应该打开一个特定页面。

我在Android 5.1上尝试了它,但是当我点击通知时,它首先打开页面,然后立即打开一个空白页面,没有任何导航栏,我不明白为什么...... < / p>

这是我的代码:

当我在android上收到消息时,我执行以下操作:

Intent intent = new Intent(this, typeof(MainActivity));
intent.PutExtra("key", "message");
PendingIntent pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);

Notification notif = new Notification.Builder(this)
                        .SetSmallIcon(Resource.Drawable.icon)
                        .SetContentTitle("Alert")
                        .SetContentText("alert message")
                        .SetAutoCancel(true)
                        .SetDefaults(NotificationDefaults.Sound | NotificationDefaults.Vibrate)
                        .SetContentIntent(pendingIntent)
                        .SetPriority((int)NotificationPriority.High)
                        .Build();

NotificationManager notificationManager = (NotificationManager)GetSystemService(Context.NotificationService);
notificationManager.Notify(0, notif);

录制时会打开MainActivity,执行以下操作:

protected override void OnCreate(Bundle bundle)
{
    TabLayoutResource = Resource.Layout.Tabbar;
    ToolbarResource = Resource.Layout.Toolbar;

    base.OnCreate(bundle);
    global::Xamarin.Forms.Forms.Init(this, bundle);
    if (app == null)
       app = new App();
    LoadApplication(app);

    // If the user tapped a notification
    if (Intent.Extras != null)
    {
        Data data = JsonConvert.DeserializeObject<Data>(Intent.Extras.GetString("key"));
        MessagingCenter.Send<Data>(data, "Show data");
    }
}

最后我有一个DataPage(设置为应用程序的MainPage,在NavigationPage中),它执行此操作:

public DataPage()
{
    MessagingCenter.Subscribe<Data>(this, "Show data", (sender) =>
    {
        await Navigation.PushAsync(new DataDetail(sender));
    });
}

我真的不明白为什么这不能正常工作...... 特别是因为我做了

await Xamarin.Forms.Application.Current.MainPage.Navigation.PushModalAsync(new NavigationPage(new DataPage(data)));

在DataPage中创建第二个构造函数:

DataPage(Data data)
{
    await Navigation.PushAsync(new DataDetail(data));
}

工作正常。 (但我不喜欢这个,它看起来非常......不太好)

2 个答案:

答案 0 :(得分:0)

我几乎无法理解您的DataDataDetailDataPageMainPage之间的联系。

就我而言,我认为Data就像是基于您的代码Data data = JsonConvert.DeserializeObject<Data>(Intent.Extras.GetString("key"));的数据模型,但在此类中您编写了代码await Navigation.PushAsync(new DataDetail(data));,此Navigation来自哪里从?

没关系,我猜您MainPage已被NavigationPage包裹,并且您希望在点击通知时将其导航到DataPage。如果是这样,那么Notification部分就没有问题了。

要显示DetailPage中的数据,您可以创建一个带参数的构造函数,例如:

public partial class DataPage : ContentPage
{
    public DataPage()
    {
        InitializeComponent();
    }

    public DataPage(int count)
    {
        InitializeComponent();
        //set the data to the UI
        label.Text = "This is Count: " + count;
    }
}

您可以在Navigation中为MainPage创建单个实例,因此可以在Data类中使用:

public static INavigation Navi;

public MainPage()
{
    InitializeComponent();
    Navi = this.Navigation;
}

然后我的Data课程如下:

public class Data
{
    public Data()
    {
        MessagingCenter.Subscribe<Data>(this, "show data", (sender) =>
        {
            MainPage.Navi.PushAsync(new DataPage(this.Count));
        });
    }

    public int Count { get; set; }
}

最后在MainActivity

protected override void OnCreate(Bundle bundle)
{
    TabLayoutResource = Resource.Layout.Tabbar;
    ToolbarResource = Resource.Layout.Toolbar;

    base.OnCreate(bundle);

    global::Xamarin.Forms.Forms.Init(this, bundle);
    LoadApplication(new App());

    if (Intent.Extras != null)
    {
        int count = Intent.Extras.GetInt("count", -1);
        var data = new Data() { Count = count };
        MessagingCenter.Send<Data>(data, "show data");
    }
}

您可以根据需要修改Data课程。以下是我的演示的渲染图像:

Here on Plunker

<强>更新

根据我们的讨论,您的消息会直接发送到DataPage,然后发送到PCL的App课程中,将DataPageNavigationPage包裹在一起:MainPage = new NavigationPage(new DataPage());

MainAcitvity这样的发送邮件中:

if (Intent.Extras != null)
{
    int count = Intent.Extras.GetInt("count", -1);
    var data = new Data() { Count = count }; //fake data, change it to your data

    var navipage = App.Current.MainPage as NavigationPage;
    var datapage = navipage.CurrentPage as DataPage;
    MessagingCenter.Send<DataPage, Data>(datapage, "show data", data);
}

DataPage

public DataPage()
{
    InitializeComponent();
    MessagingCenter.Subscribe<DataPage, Data>(this, "show data", (sender, arg) =>
    {
        Navigation.PushAsync(new DataDetail(arg));
    });
}

当然,我们需要在DataDetail中使用参数:

创建一个教师
public DataDetail(Data data)
{
    InitializeComponent();
}

答案 1 :(得分:0)

所以我终于解决了这个问题。 这似乎是因为我在MainActivity中创建了一个静态App变量,只创建了一次。

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    static App app;

    protected override void OnCreate(Bundle bundle)
    {
        ...
        if(app == null)
            app = new App();
        ...
     }
}

我这样做是因为否则重置了app实例的Current.Properties。

现在我改变了,我不再有这个问题了: 我调用Current.SavePropertiesAsync()来保存Current.Properties,因此我可以在MainActivity中删除App的静态实例。它解决了空白页问题。

但这又造成了另一个问题。当我点击通知时,它第一次正常工作,但之后它多次打开请求的页面(第二个通知点击打开2页,第三个打开3,......)。我不明白为什么会这样做,但它似乎是由MessagingCenter引起的。所以我删除了MessagingCenter部分,只是在MainActivity中执行了这个:

if (Intent.Extras != null)
{
     Data data = JsonConvert.DeserializeObject<Data>(Intent.Extras.GetString("key"));
     DataPage currentPage = (DataPage)((NavigationPage)App.Current.MainPage).CurrentPage;
     currentPage.OpenDataDetails(data);
}

在DataPage中我有这个功能

public async void OpenDataDetails(Data data)
{
    await Navigation.PushAsync(new DataDetail(data));
}

这确实按预期工作,所以现在我很高兴。

但是,我仍然不明白为什么当我在MainActivity中有一个静态App实例时,它打开了一个空白页面,也没有为什么它用MessagingCenter打开多个页面...