当页面被推送到NavigaionPage

时间:2017-02-11 00:08:49

标签: android xamarin.android xamarin.forms master-detail custom-renderer

我拿了我在这里找到的来源: https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Platform.Android/Renderers/MasterDetailRenderer.cs

并在Xamarin Forms Android项目中创建了自定义渲染器。我得到了要构建的项目和按预期打开/关闭的菜单,以及显示起始详细信息页面。

详细信息页面是Xamarin.Forms中的“NavigaionPage”,它实际上只是一个带有一堆代码的ViewGroup,可以使它与推/弹功能一起使用。

当我推送一个新的页面,一个具有自定义渲染器和本机RelativeLayout作为子视图的页面时,页面显示为空白,直到我旋转方向。

在对代码进行一些研究之后,我意识到OnMeasure和OnLayout都没有在页面中被调用,而页面正被推送到NavigationPage /详细页面(推送页面的大小在0x0之前保持不变,直到方向改变)。

我创建了另一个自定义渲染器,但这次是针对NavigationPage的,如下所示:

public class MasterDetailContentNavigationPageRenderer : NavigationPageRenderer 
{

  protected override void OnElementChanged(ElementChangedEventArgs<NavigationPage> e)
  {
    base.OnElementChanged(e);

    if(e.OldElement != null)
    {
      e.OldElement.Pushed -= handleOnPushed;
    }

    if(e.NewElement != null)
    {
      e.NewElement.Pushed += handleOnPushed;
    }
  }

  private void handleOnPushed(object sender, EventArgs e)
  {
    var w = MeasureSpec.MakeMeasureSpec(MeasuredWidth, MeasureSpecMode.Exactly);
    var h = MeasureSpec.MakeMeasureSpec(MeasuredHeight, MeasureSpecMode.Exactly);
    Measure(w, h);
    Layout(Left, Top, Right, Bottom);
  }
}

此详细信息页面/ NavigaionPage的自定义渲染器适用于我推送的3个页面中的2个。

主要/最重要的页面没有完全添加所有UI元素。

推送和缺少UI的页面具有一些UI。以下是页面显示方式的列表:

--- SongViewerLayout:RelativeLayout

------ RelativeLayout

--------- ViewerTopBar(绘制除一个之外的所有按钮)

--------- DocumentView(顶栏和分页之间的空白点)

--------- ViewerPagination(绘制背景颜色但不绘制页面按钮)

如果我更改了方向,则顶部栏中会显示缺失的按钮,页面编号会显示,而文档视图则会绘制,但它会关闭。

如果我回到使用Xamarin.Forms提供的MasterDetailPage,UI就会按预期加载。

我已经研究了Xamarin.Forms repo中的代码,但它们都没有真正适用于添加元素的内部工作方式。换句话说,详细信息页面(在我的情况下是一个NavigationPage)被添加到SetElement(...)上并且分配了一些处理程序......但是我没有告诉它查找被推送然后响应的页面。我假设/期望NavigationPage只是按预期工作,因为它是MasterDetailPage / DrawerLayout的子视图。

注意:似乎具有最多问题的视图是以编程方式添加的,并给出了“LayoutParamaters”。 AXML中的视图似乎只是出现了。

  • 我是否缺少在Android中“初始化”布局?我在Android中制作了原生应用,而不必做任何特别的事情。

  • 为什么NavigationPage上方的UI会导致NavigationPage不进行标准初始化?

  • 我缺少什么?

编辑:

我在我的GitHub帐户上创建了一个这个问题的工作示例,您可以在此处克隆: https://github.com/XamarinMonkey/CustomMasterDetail

  1. 构建并运行CustomMasterDetail.Droid(注意UI是MasterDetailPage)

  2. 点按任意项目

  3. 底部的蓝色条没有页码。

  4. 显示页码的旋转方向。

  5. 停止构建

  6. 注释掉整个班级“MainMasterDetailPageRenderer.cs”

  7. 重建/运行应用

  8. 点按任意项目

  9. 页面编号会立即显示,因为它现在使用的是默认的MasterDetailPage!

  10. 请提出建议!

  11. 编辑#2:

    感谢一些反馈,它似乎不是6.0设备中的问题。我的测试设备是带有v5.1.1的“Samsung Galaxy Tab Pro”。不幸的是,我需要这个应用程序回到4!

    编辑#3:

    问题必须是在Android 5.1.1中以编程方式将一个视图添加到本机RelativeLayout(它被推送到NavigationPage详细页面)后,在Xamarin.Forms中膨胀。手动调用测量/布局似乎可以解决问题。但我需要一个更自动化的解决方案。

1 个答案:

答案 0 :(得分:0)

我提出了一个有效的解决方案。它可能很昂贵但似乎在我测试的设备上快速布局。

基本上,我在Android上阅读并找到了一种方法来监听布局更改,使用ViewTreeObserver.GlobalLayout事件并在详细信息和主ViewGroups上调用Measure / Layout。

public void MeasureAndLayoutNative()
{
    if(_childView != null)
    {
        IVisualElementRenderer renderer = Platform.GetRenderer(_childView);
        if(renderer.ViewGroup != null)
        {
            var nativeView = renderer.ViewGroup;

            var w = MeasureSpec.MakeMeasureSpec(nativeView.MeasuredWidth, MeasureSpecMode.Exactly);
            var h = MeasureSpec.MakeMeasureSpec(nativeView.MeasuredHeight, MeasureSpecMode.Exactly);
            nativeView.Measure(w, h);
            nativeView.Layout(nativeView.Left, nativeView.Top, nativeView.Right, nativeView.Bottom);
        }
    }
}

我使用工作更改更新了上面的代码示例!