Android 为什么FindViewById在从纵向切换到横向时返回null?
我的一个活动的InitView方法调用其属性Android 为什么FindViewById在从纵向切换到横向时返回null?,android,xamarin,Android,Xamarin,我的一个活动的InitView方法调用其属性 protected ListView MainMenu { get { return FindViewById<ListView>(Resource.Id.mainmenu); } } 正如所料。值得注意的是,通过设置ConfigurationChanges=ConfigChanges.orientation和ConfigChanges.Screen
protected ListView MainMenu
{
get
{
return FindViewById<ListView>(Resource.Id.mainmenu);
}
}
正如所料。值得注意的是,通过设置ConfigurationChanges=ConfigChanges.orientation和ConfigChanges.ScreenSize手动处理方向更改会使横向模式正常工作。这是Xamarin的问题,还是我误解了什么?1)创建一个名为drawable land的文件夹
2) 将xml文件复制并粘贴到此文件夹中,然后再次运行应用程序并尝试更改方向。在纵向模式下为此活动生成的布局中不存在id为“mainmenu”的元素。因此,FindViewById返回null。您需要确保纵向模式布局包含“mainmenu”元素,或者执行空检查,例如:
if (MainMenu != null) {
MainMenu.Visibility = ViewStates.Visible;
}
…然后才能访问MainMenu属性。(注意:在访问并非所有布局中都存在的元素之前,简单地检查设备方向可能会导致细微的错误,不应该这样做)
我自己的问题的详细答案是,该活动实际上并没有在其InitView中调用SetContentView(Resource.Layout.MainMenuLayout),而是使用SetContentView(Resource.Layout.MasterLayout)。所以我们需要看MasterLayout.axml,而不是MainMenuLayout.axml。更重要的是MasterLayout.axml有两个版本,一个在“layout port”文件夹中,另一个在“layout”文件夹中。“布局”中的一个具有include指令
<include layout="@layout/MainMenuLayout" />
…但“布局端口”中的版本没有此包含。这就是为什么元素“mainmenu”只存在于横向布局中,而不存在于纵向布局中
这个故事的寓意是:在布局中使用include指令时,要使您的房子井然有序
[编辑:详细说明“细微缺陷”此响应中的注意事项:如果在访问仅以纵向模式存在的元素(例如纵向模式)之前,使用WindowManager.DefaultDisplay.Rotation检查设备方向,FindViewById仍然可以返回null。在Xamarin上,活动可能处于设备方向为纵向但尚未创建纵向视图元素的状态。这如果在切换活动后立即快速翻转设备,则可能会发生这种情况。活动的不一致版本将使用正确的配置快速停止和恢复,但它可能会持续足够长的时间,以便代码执行并获得NullReferenceException。这就是为什么您应该检查FindViewById是否返回null、 而且不仅仅是看设备配置]。我不确定执行空检查是否有助于其他人,更不用说默认情况下应该断言空引用了。此外,视图不应在每次访问时加载。只有当视图不存在时,才应分配它。。。但那只是我的20美分 在我的例子中,findViewByID返回了一个空值,因为我在活动中调用了它,但是视图在层次上属于片段 因此,您只需将MainMenu属性移动到片段,然后通过活动中的片段访问它:
myFragment.MainMenu
文件夹布局区域中是否有第二个文件?否,文件夹布局区域不存在。(layout-sw820dp和layout-sw720dp-port都有,但它们都不包含类似名称的axml文件)。尝试在横向模式下启动它并将其切换到纵向模式,它会启动吗?会发生什么?是否使用片段?在横向模式下启动会立即引发NullReferenceException。我没有使用碎片,为什么?感谢您的输入:)(另外,将视图文件添加到布局区域文件夹不会导致任何改进)。
<include layout="@layout/MainMenuLayout" />
myFragment.MainMenu