该应用程序的根页面包括TabbedPage,其中包括NavigationPage。NavigationPage定义的属性Navigation返回实现了接口INavigation的对象。这样,就可以使用PushAsync方法导航到另一个页面,并使用PopAsync方法返回。
使用.NET标准库Framework,用这些方法定义INavigationService:
public interface INavigationService
{
bool UseNavigation { get; set; }
Task NavigateToAsync(string page);
Task GoBackAsync();
string CurrentPage { get; }
}
现在,需要Xamarin.Forms的具体实现。
public class XamarinNavigationService : INavigationService
{
private Dictionary<string, Func<Page>> _pages = new Dictionary<string, Func<Page>>
{
[PageNames.BooksPage] = () => new BooksPage(),
[PageNames.BookDetailPage] = () => new BooksDetailPage()
};
private Stack<string> _pageStack = new Stack<string>();
private bool _initialized = false;
private void Initialize()
{
if (!_initialized)
{
_navigation = _initializeNavigation.Navigation ?? throw new InvalidOperationException($"{nameof(_initializeNavigation.Navigation)} not initialized");
_pageStack.Push(_initializeNavigation.IntialPage);
_initialized = true;
}
}
private string initialPage;
private INavigation _navigation;
private INavigation Navigation
{
get => _navigation;
}
public string CurrentPage
{
get
{
Initialize();
return _pageStack.Peek();
}
}
public bool UseNavigation { get; set; }
private readonly XamarinInitializeNavigationService _initializeNavigation;
public XamarinNavigationService(XamarinInitializeNavigationService initializeNavigation) =>
_initializeNavigation = initializeNavigation ?? throw new ArgumentNullException(nameof(initializeNavigation));
public Task GoBackAsync()
{
_pageStack.Pop();
return Navigation.PopAsync();
}
public Task NavigateToAsync(string pagename)
{
_pageStack.Push(pagename);
return Navigation.PushAsync(_pages[pagename]());
}
}
现在需要为初始化提供XamarinInitializeNavigationService。这个类只定义了XamarinNavigationService类使用的Navigation属性,和SetNavigation方法:
public class XamarinInitializeNavigationService
{
public void SetNavigation(INavigation navigation, string initialPage)
{
_navigation = navigation;
_initialPage = initialPage;
}
private string _initialPage;
private INavigation _navigation;
public INavigation Navigation => _navigation ?? throw new ArgumentException("navigation not initialized");
public string IntialPage => _initialPage;
}
现在,需要从NavigationPage可用的页面中设置Navigation属性——MainPage的代码隐藏文件:
public partial class MainPage : TabbedPage
{
public MainPage()
{
InitializeComponent();
(Application.Current as App).AppServices
.GetService<XamarinInitializeNavigationService>()
.SetNavigation(navigationPage.Navigation,PageNames.BooksPage);
}
}