使用Xamarin.Forms进行导航

时间:2016-09-21 12:48:14

标签: mvvm xamarin xamarin.forms uinavigation

尝试使用Xamarin.Forms页面找到实现导航的最佳方式。

这是我的UI导航图 UI navigation diagram

我正在使用mvvm。每个ViewModel都填充了INavigationService。

public class NavigationService : INavigationService
{
    private readonly NavigationPage navigationPage;

    private const string PageNameTemplate = "Mmv.MMTravel.CrossPlatform.Views.{0}, Mmv.MMTravel.CrossPlatform";

    public NavigationService(NavigationPage page)
    {
        navigationPage = page;
    }

    public string CurrentPageKey
    {
        get
        {
            return navigationPage.CurrentPage.GetType().Name;
        }
    }

    public async Task GoBackAsync()
    {
        await navigationPage.Navigation.PopAsync();
    }

    public async Task NavigateAsync(string pageKey, object parameter)
    {
        await CallOnNavigateFrom();
        var page = CreatePage(pageKey);
        await CallOnNavigateTo(page, parameter);
        if (Device.OS == TargetPlatform.Android)
        {
             Device.BeginInvokeOnMainThread(() =>
            {
                navigationPage.Navigation.PushAsync(page);
            });
        }
        else
        {
            await navigationPage.Navigation.PushAsync(page);
        }
    }

    public async Task NavigateAsync(string pageKey)
    {
        await NavigateAsync(pageKey, null);
    }

    public async Task SetAndNavigateToRootPage(string pageKey, object parameter)
    {
        await CallOnNavigateFrom();
        var page = CreatePage(pageKey);
        await CallOnNavigateTo(page, parameter);
        navigationPage.Navigation.InsertPageBefore(page, navigationPage.Navigation.NavigationStack.First());
        await navigationPage.PopToRootAsync(false);
    }

    public async Task SetAndNavigateToRootPage(string pageKey)
    {
        await SetAndNavigateToRootPage(pageKey, null);
    }

    public async Task NavigateModalAsync(string pageKey, object parameter)
    {
        await CallOnNavigateFrom();
        var page = CreatePage(pageKey);
        await CallOnNavigateTo(page, parameter);
        await navigationPage.Navigation.PushModalAsync(page);
    }

    public async Task NavigateModalAsync(string pageKey)
    {
        await NavigateModalAsync(pageKey, null);
    }

    public async Task GoBackModalAsync()
    {
        await navigationPage.Navigation.PopModalAsync();
    }

    private Page CreatePage(string pageKey)
    {
        var typeName = string.Format(PageNameTemplate, pageKey);
        var pageType = Type.GetType(typeName);
        var page = Activator.CreateInstance(pageType) as Page;
        return page;
    }

    private async Task CallOnNavigateTo(Page page, object parameter)
    {
        var vm = page.BindingContext as INavigateAwareViewModel;
        if (vm != null && !vm.IsBusy) 
        {
            await vm.OnNavigatedTo(parameter).ConfigureAwait(false);
        }
    }

    private async Task CallOnNavigateFrom()
    {
        if (navigationPage.CurrentPage != null)
        {
            var prevVM = navigationPage.CurrentPage.BindingContext as INavigateAwareViewModel;
            if (prevVM != null && !prevVM.IsBusy)
            {
                await prevVM.OnNavigatedFrom().ConfigureAwait(false);
            }
        }
    }
}

如您所见,我的NavigationService包含NavigationPage。因此,所有导航都通过NavigationPage中的Navigation属性进行。 此外,每个viewmodel都具有异步init的OnNvaigateTo()和OnNavigateFrom()方法。 当应用程序启动时,我将App.cs中的MainPage属性设置为NavigatioService中的navigationPage

问题#1

通过页面#1 - #3实现导航(在UI导航图上) 我使用 SetAndNavigateToRootPage 方法

例如,当用户从第1页INTRO导航到第2页ACCOUNT时。 enter image description here

我调用Navigation属性的InsertPageBefore()方法。 enter image description here

然后是PopToRootAsync()方法。 enter image description here

我找到了实现这一目标的新方法。只是将App.cs中的MainPage属性设置为新页面。

请告诉我您的意见哪条路更好?

  • 使用SetAndNavigateToRootPage

  • 在App.cs中设置MainPage属性

问题#2

有MasterDetailPage(#5)

问题是,当我从第3页MAIN NENU导航到第5页BurgerMenu时,根据我目前的实现,我有这个:

enter image description here

根据Xamarin的文件:

enter image description here

使用MasterDetailPage填充NavigationPage不是一个好主意......

我应该更改我的NavigationService并使用App.cs中的MainPage属性,而不是将所有内容都放在NavigationPage中,不应该吗?

0 个答案:

没有答案