我拿了我在这里找到的来源: 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
构建并运行CustomMasterDetail.Droid(注意UI是MasterDetailPage)
点按任意项目
底部的蓝色条没有页码。
显示页码的旋转方向。
停止构建
注释掉整个班级“MainMasterDetailPageRenderer.cs”
重建/运行应用
点按任意项目
页面编号会立即显示,因为它现在使用的是默认的MasterDetailPage!
请提出建议!
编辑#2:
感谢一些反馈,它似乎不是6.0设备中的问题。我的测试设备是带有v5.1.1的“Samsung Galaxy Tab Pro”。不幸的是,我需要这个应用程序回到4!
编辑#3:
问题必须是在Android 5.1.1中以编程方式将一个视图添加到本机RelativeLayout(它被推送到NavigationPage详细页面)后,在Xamarin.Forms中膨胀。手动调用测量/布局似乎可以解决问题。但我需要一个更自动化的解决方案。
答案 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);
}
}
}
我使用工作更改更新了上面的代码示例!