在最初接触Xamarin.Forms的时候,我是跟着Xamarin官方的名为“learning-xamarin-ebook”的pdf文档进行学习的,我在成功运行Hello world程序之后,我开始跟着pdf写上面的monkey实例,然而我却遇到了一个问题,我在列表页点击某一个Item的时候,不能如示例上面所展示的那样跳转到详细页面。也正因为此我在官方文档和电子书中寻找答案,也将自己的学习的东西做个简单的笔记和分享。

  在Froms的中的提供了如下方法用于导航:

  Task PushAsync(Page page)和Task PushModalAsync(Page page)导航到其他页面;

  Task<Page> PopAsync()和Task<Page> PopModalAsync()返回到前一页;

  这四个方法都被定义在一个INavigation接口中,而VisualElement中又定义了一个名为Navigation的只读的INavigation的属性,其他Page又直接或间接继承了这个类。所以我们可以在代码中直接做如下调用:

  await Navigation.PushAsync(Page page)

  await Navigation.PopAsync()

  然而你要想成功调用这四个导航方法,你必须在App类的构造函数中做一些改变,即使用NavigationPage对你得主页(MainPage)做一个简单的封装,而这也就是我先前跳转页面不成功的原因,如下:

  

  为什么要这样呢?因为毕竟跨平台,只有这样才能在各个平台上实现Page的生命周期,其实就是为了兼容Android(毕竟英文,有些记得不是太清楚,有问题大家指正)。这四个方法都提供了另一个重载,都多了一个参数:bool animated(默认为true),根据参数名,你应该也知道这个参数的作用了,但实际上,默认的跳转页面的动画还算可以,通用的那种,当然貌似也可以重写,在电子书的动画那章应该有讲,不过目前我还没看。。。。。。

  好了,在继续正题之前,还有两个要点,一是在Froms中的Page在各个平台中是不一样的,一个Froms的Page相当于IOS的view Control,也相当于WP的Page,但是并不是Android的Activity,这里给大家给大家贴一下电子书中的原文,官网中的自己搜一下就行

  Programmers familiar with Android architecture are sometimes curious how Xamarin.Forms page navigation integrates with the aspect of Android application architecture known as the activity. A Xamarin.Forms application running on an Android device comprises only one activity, and the page navigation is built on top of that. A ContentPage is a Xamarin.Forms object; it is not an Android activ-ity, or a fragment of an activity.

  也正是因为各个平台的不同,Page中的可重写的方法的调用顺序也多不同。这个后面说。第二个就是modal page和modeless page,正常的讲在各个平台都没有对他们明确的区分和定义,在视觉上最直观的区别就是默认情况下(导航栏也是可以通过设置进行显示和隐藏)在左上角是否有返回按钮(WP没有,WP和Android都有返回的物理按键,只不过Android在页面也有返回键),而在代码中则体现为跳转页面时调用的是PushAsync还是PushModalAsync方法。如下图(截得的电子书中的图):

  

  如上图左边是modeless page而右边则是modal page,正如你所看到的,如果你跳转的页面是modeless page在各个平台,你是不需要在页面中再提供返回按键的,而modal page则有不同,由于WP和Android都有物理的返回按键支持,所以如果你在modal page中不提供返回按钮,也并没有关系,然而在IOS中,你必须提供,为什么,当然是因为它没有提供返回的物理按键,只有Home键。当然WP和Android的物理返回按键也是也已禁用的,如果你存在非要用户完成某些操作的“流氓”行为,就是重写OnBackButtonPressed方法即可,如下:

        protected override bool OnBackButtonPressed()
{
if(flag)
{
return base.OnBackButtonPressed();
}
return true;
}

  并且modal page只能跳转到另一个modal page,而modeless page能跳转到modal page和modeless page。

  现在说一下NavigationPage的常用属性和方法:

  1、BarBackgroundColor和BarTextColor都是Color类型的属性,看名字就知道其用途,这两个属性在IOS和Win10都会生效,在Android上去只有背景色(BarBackgroundColor)会生效.

  代码如下:  

        public static Page GetMainPage()
{
var monkeyPage = new MonkeysPage();
return new NavigationPage(monkeyPage) { BarBackgroundColor=Color.Green,BarTextColor=Color.Blue };
}

  如图(我只有安卓机,所以自己的图只有安卓的,对比图我就直接截电子书的,以后都是):

  

  官方免费电子书对比图如下:

  

  2、SetBackButtonTitle方法,这个只有IOS才会生效,应为只有IOS会显示前一页的Title。

  3、SetTitleIcon方法,这个在IOS中将替换Title属性,Android替换图标。

  以上两个并不会作用于Windows和WP。

  4、SetHasNavigationBar和SetHasBackButton这两个就是分别设置是否显示导航栏和是否显示导航栏的的返回图标。

  方法并不能在App中设置,只能在Page的构造函数中设置,调用方式如下:

namespace App3.Views
{
public partial class DetailsPage : ContentPage
{
public DetailsPage(Monkey monkey)
{
InitializeComponent();
       //其他方法大同小异
NavigationPage.SetHasNavigationBar(this, false);
this.BindingContext = monkey;
}
}
}

  

 咱们继续,当我们调用Push或者Pop方法是返回的总是Task对象,是不是意味着如果我们使用await来调用方法,会出现等待呢?官方的描述为:task completes rather quickly。而且官方建议在调用Push或者Pop方法的时候,一定要用await,为什么?因为在某些情况下page stack是不安全的,我需要使用await来确保已经获取到了下一个页面的实例,并且已安全的写入到了page stack中。如果你在看这篇文章的时候你也F12到了INavigation接口中,你会看到接口内定义了两个IReadOnlyList<Page>的对象。

  

  IReadOnlyList<T>看名字你就知道他是一个只读的,但是他跟Stack<T>相似,都是先进后出,或者你就把它当作是Stack<T>理解也行,只不过前者是只读的而已。在IOS中ModalStack始终为空的。

  我们NavigationPage对象中的CurrentPage的值为NavigationStack的最后一个进栈的,简单点就是CurrentPage如果有值,那只能是modeless page。

  

  在Page对象中我们还看到了两个可以重写的方法:

  protected virtual void OnDisappearing();

  protected virtual void OnAppearing();

  这两个方法又是什么时候执行,执行顺序又是什么?我们这里用PushAsync和PushModalAsync:

  1、页面调用PushAsync或者PushModalAsync通常将会获取当前页面的OnDisappearing方法重写的调用

  2、然后获取下一个页面的OnAppearing方法的重写的调用

  3、PushAsync或者PushModalAsync完成

  而当我们调用PopAsync或者PopModalAsync的执行顺序如下:

  1、页面调用PopAsync或者PopModalAsync将会获取当前页面的OnDisappearing方法重写的调用

  2、然后通常获取上一个页面的OnAppearing方法的重写的调用

  3、PopAsync或者PopModalAsync完成

  是的,我把”通常“用红色的标注了,为什么,先前也说过Froms Page并不是一个Android的Actively,所以有些不同,调用PushModalAsync的时候不会调用OnDisappearing,而调用PopModalAsync的时候是不会调用前一页的OnAppearing,至于为什么,当我把下一个页面设置为透明(在构造函数中设置BackgroupColor=Color.FromRgba(0,0,0,0.5)),然后用modal page的方式导航过去的时候就知道了,如下图:

    

  是的,如你所见,前一页并没有销毁,而是存在的,so。。。不需要我再解释了吧!如果你非要问为什么没有销毁,我的答案是:呵呵!

  而在IOS中,OnDisappearing的调用是在一个页面完全销毁的时候,而不是在调用Push或者Pop的时候。

  好了,就这么,艰苦的一年啊!

Xamarin.Forms学习之Page Navigation(一)的更多相关文章

  1. Xamarin.Forms学习之Page Navigation(二)

    在上一篇的文章中,对页面常规的导航做一些分享,然而在实际的编程中,页面数据的保持,传值等等都有很多,这篇文章就对这些相关内容做一个分享和记录,有问题,希望大家留言指正.这一篇从实现业务逻辑来讲并没有什 ...

  2. Xamarin.Forms学习之XAML命名空间

    大家好,我又悄咪咪的来了,在上一篇的Xamarin文章中简单介绍了Xamarin的安装过程,妈蛋没想到很多小朋友很感激我,让他们成功的安装了Xamarin,然后......成功的显示了经典的两个单词( ...

  3. Xamarin.Forms学习之Platform-specific API和文件操作

    这篇文章的分享原由是由于上篇关于Properties的保存不了,调用SavePropertiesAsync()方法也不行,所以我希望通过操作文件的方式保存我的需要的数据,然后我看了一下电子书中的第二十 ...

  4. Xamarin.Forms学习之初

    微软的Build 2016结束的有段时间了,对于一个简单的小屌丝程序员--我来说,关注最大的无疑是Xamarin的免费(开源什么的让大神们上吧),内心激动啊.大会结束的周末我就迫不及待的安装了,然后. ...

  5. Xamarin.Forms学习系列之Android集成极光推送

    一般App都会有消息推送的功能,如果是原生安卓或者IOS集成消息推送很容易,各大推送平台都有相关的Sample,但是关于Xamarin.Forms的消息推送集成的资料非常少,下面就说下Xamarin. ...

  6. Xamarin.Forms 学习系列之底部tab

    App中一般都会有一个底部tab,用于切换不同的功能,在Xamarin中应该制作底部tab了,需要把Android的TabbedPage做一次渲染,IOS的则不用,接下来说下详细步骤: 1.在共享项目 ...

  7. Xamarin.Forms学习之位图(二)

    上篇文章分享了如何加载网络图片和PCL中的图片,所以今天继续分享关于如何加载平台的内嵌图片,在这之前说一下上篇文章开头的一个问题:为什么不能加载UWP项目,这是因为我升级了UWP的SDK,而Xamar ...

  8. Xamarin.Forms 学习系列之优秀UI收集

    1.各种优秀UI例子 https://github.com/jsuarezruiz/xamarin-forms-goodlooking-UI 输入框例子 https://github.com/enis ...

  9. Xamarin.Forms学习系列之Syncfusion 制作图形报表

    Syncfusion是一家微软生态下的第三方组件/控件供应商,除了用于HTML5和JavaScript的控件外,他们产品还涉及如下领域: WEB ASP.NET MVC ASP.NET WebForm ...

随机推荐

  1. 手机号码月消费档次API

    手机号码月消费档次API,返回手机号的每月消费水平,身份证姓名不做一致性校验 文档:https://www.juhe.cn/docs/api/id/261 接口地址:http://v.juhe.cn/ ...

  2. pcap学习

    #include <pcap.h> char errbuf[PCAP_ERRBUF_SIZE]; pcap_t *pcap_open_live(const char *device, in ...

  3. 访问vector元素方法的效率比较(转)

    LInux下: gcc 4.47,red hat6 #include<iostream> #include<vector> #include<time.h> usi ...

  4. Refactoring之——代码的坏味道(一)过长方法

    1 代码的坏味道 重构一书中提到了22种代码的坏味道,大致可以分为几类. 识别代码的坏味道,有助于发现代码的潜在问题,从而可以有的放矢的修改现有代码,使之不断完善. 1.1 Bloaters(臭鲱,暂 ...

  5. udpsocket 通信C#例子

    服务端代码: using System; using System.Collections.Generic; using System.Linq; using System.Net; using Sy ...

  6. BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览 client对象模型API范围

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览 client对象模型API范围         本章之前提到过. ...

  7. 使用apxs安装apache模块

    使用apxs安装apache模块                 ---by石锅拌饭 1.缘由 前几天迁移系统.发现配置了fastcgi的一个脚本下载文件总是提示类似Connection reset ...

  8. nginx configure参数

    下面是nginx源码程序的configure参数: --prefix= 指向安装目录.默认为:/usr/local/nginx --sbin-path= 指定执行程序文件存放位置.默认为:prefix ...

  9. match函数

    match(s, r [, a]) Return the position in s where the regular expression r occurs, or 0 if r is not p ...

  10. iOS一些基础面试题

    Part One 别人问你你都感觉这尼玛说啥的基础面试题 1.UIWindow和UIView和 CALayer 的联系和区别? 答:UIView是视图的基类,UIViewController是视图控制 ...