0

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

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

详细信息页面是 Xamarin.Forms 中的“NavigaionPage”,它实际上只是一个带有一堆代码的 ViewGroup,以使其与 Push/Pop 函数一起使用。

当我推送一个具有自定义渲染器和原生 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 个。

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

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

--- SongViewerLayout : 相对布局

------ 相对布局

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

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

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

如果我更改方向,缺少的按钮会出现在顶部栏中,页码会显示,并且文档视图会被绘制,但它已关闭。

如果我返回使用 Xamarin.Forms 提供的 MasterDetailPage,则 UI 将按预期加载。

我研究了 Xamarin.Forms 存储库中的代码,但没有一个真正适用于所添加元素的内部工作。换句话说,详细信息页面(在我的例子中是 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. 请给建议!

编辑#2:

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

编辑#3:

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

4

1 回答 1

1

我想出了一个可行的解决方案。它可能很昂贵,但似乎在我测试过的设备上布局很快。

基本上,我阅读了 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);
        }
    }
}

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

于 2017-02-14T03:30:53.163 回答