Xamarin.Forms学习之Page Navigation(一)

  在最初接触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,所以有些不同,调用PushAsync或者PushModalAsync的时候不会调用OnDisappearing,而调用PopAsync或者PopModalAsync的时候是不会调用前一页的OnAppearing,至于为什么,当我把下一个页面设置为透明(在构造函数中设置BackgroupColor=Color.FromRgba(0,0,0,0.5)),然后用modal page的方式导航过去的时候就知道了,如下图:

    

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

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

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

时间: 2024-08-05 02:31:53

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

Xamarin.Forms学习之Page Navigation(二)

在上一篇的文章中,对页面常规的导航做一些分享,然而在实际的编程中,页面数据的保持,传值等等都有很多,这篇文章就对这些相关内容做一个分享和记录,有问题,希望大家留言指正.这一篇从实现业务逻辑来讲并没有什么特别的,这里主要是说说通过Properties和生命周期实现数据的“保持”.当然这里遇到了一个让我懵逼的问题,电子书中介绍说,Properties的值是会一直保持的,直到App卸载,但是在我的安卓机中实验,程序终止后,值就为空了,不知是我看掉了什么东西还是怎么了,不知道大家有没有遇到这个问题,希望

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

这篇文章的分享原由是由于上篇关于Properties的保存不了,调用SavePropertiesAsync()方法也不行,所以我希望通过操作文件的方式保存我的需要的数据,然后我看了一下电子书中的第二十章和需要相关知识的第九章,这篇文章中的内容则是我学习这两章的一点记录和分享,还是那样,有错请留言指正,谢谢! 不同的平台存在着一些特定的API,通过在电子书中两章的学习,实践一下如何调用这些API和将这些API封装成公共的库,供以后的项目调用.以一个显示平台信息的小实例开始做一个简单的演示,其运行效

Xamarin.Forms学习之初

微软的Build 2016结束的有段时间了,对于一个简单的小屌丝程序员--我来说,关注最大的无疑是Xamarin的免费(开源什么的让大神们上吧),内心激动啊.大会结束的周末我就迫不及待的安装了,然后...一脸的懵逼,更新vs后什么sdk,jdk都不知道,唯一知道的就是没法运行,后来大神们相继出了一些文章,才开始了解一些大概,有错误的请在下面留言提出,免得我误导了别人. xamarin可以简单分为一下几个: Xamarin.Forms:个人觉得这才是Xamarin真正的优势所在,真正的跨平台,一次

Xamarin.Forms学习之位图(二)

上篇文章分享了如何加载网络图片和PCL中的图片,所以今天继续分享关于如何加载平台的内嵌图片,在这之前说一下上篇文章开头的一个问题:为什么不能加载UWP项目,这是因为我升级了UWP的SDK,而Xamarin还没有支持到这个版本(我也不想用Xamarin来发UWP项目).还有就是园友问怎么知道哪些是平台特殊的API(Platform-specific API和文件操作),自认为呢,当你调用一个API的时候需要引用Xanmarin.IOS和Mono.Android或者说除了.NET的API都算是Pla

Xamarin.Forms学习之位图(一)

在开始我的分享之前呢,让我先问下我的问题: 1.最近更新了Xamarin 4.1.1.3,我想问下版本更新信息在哪里看? 2.更新后我新建的项目没有UWP项目了(虽然没有用过,但是我想确认是4.1.1.3移除了还是我自身的问题),其实我觉得移除了也好,UWP就用UWP写最好了! 3.我的模拟器无法使用,是我安装的问题还是说有其他的设置? 再吐个槽: 1.Xamarin.Froms早已经更新到了2.3了,但是vs的模板一直没更新(还是说可以其他设置更新?还是说2.3不稳定?),导致新建的项目的Fr

Xamarin.Forms bug? System.ObjectDisposedException: Cannot access a disposed object

Hi, My Android Xamarin.Forms application uses a Navigation stack to display various views, I often have a list on a screen (A) that once a cell is clicked I push onto the stack a new screen (B), the user completes some form fields and then clicks a b

Xamarin.Forms中 Navigation,NavigationPage详解

1.Xamarin Forms下有四个成员类:Element,VisualElement,Page,NavigationPage 基类为Element,继承的子类分别是VisualElement,Page,NavigationPage. 2.Navigation 为VisualElement的一个成员对象,该对象是INavigation接口类型的. 3.INavigation接口中有5个方法,如下 namespace Xamarin.Forms { public interface INavig

Xamarin.Forms WebView

目前本地或网络的网页内容和文件加载 WebView是在您的应用程序显示Web和HTML内容的视图.不像OpenUri,这需要用户在Web浏览器的设备上,WebView中显示您的应用程序内的HTML内容. 本指南由以下几部分组成: 内容?- web视图支持各种内容源,包括嵌入的HTML,网页和HTML字符串. 导航?-网页视图包括导航到特定页面,回到主页. 活动?–监听并通过在WebView中用户所采取的行动作出回应. 性能?-了解的WebView的每个平台上的性能特点. 权限?-了解如何设置权限

Xamarin.Forms 调用 腾讯地图SDK

Xamarin.Forms研究了好一段时间了,最近一直在学习中,想尝试一下调用其他的SDK,就如腾讯地图SDK(申请容易). 完成此次项目得感谢以下链接: http://www.cnblogs.com/jtang/p/4698496.html 其他文档参考: 腾讯地图SDK(安卓)文档 这里面有详细的使用过程(当然里面的代码是不适用C#的,不过要从这里下载SDK,也有如何申请Key的过程,请参考阅读) Xamarin.Forms自定义每个平台的控件文档 里面有如何根据不同的平台条件下,调用其他页