我的一个活动的InitView方法调用其属性
protected ListView MainMenu
{
get
{
return FindViewById<ListView>(Resource.Id.mainmenu);
}
}
...指的是ListView被定义为RelativeLayout&#34; MainMenuLayout.axml&#34;的一部分。位于&#34;布局&#34;我的Android项目中的文件夹:
<ListView
android:id="@+id/mainmenu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice"
android:layout_below="@id/mainmenuHeader"
android:divider="#e5e5e5"
android:dividerHeight="1dp"
android:background="#fff" />
在纵向模式下,此操作符合预期。但是,当切换到横向模式时,对上面的FindViewById的调用返回null。据我所知,Android应该使用布局文件夹进行纵向和横向模式。 Resource.designer.cs还包含
public const int mainmenu = 2131492931;
正如所料。值得注意的是,通过设置ConfigurationChanges = ConfigChanges.Orientation和ConfigChanges.ScreenSize手动处理方向更改会导致横向模式正常工作。这是一个Xamarin问题,还是我误解了什么?
答案 0 :(得分:2)
在纵向模式下为此活动生成的布局中不存在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”中。 “layout”中的那个具有include指令
<include layout="@layout/MainMenuLayout" />
...但是“layout-port”中的版本没有这个包含。这就是元素“mainmenu”仅存在于横向布局而不是纵向的原因。
故事的道德:在布局中使用include指令时,保持房屋整洁。
[编辑:要详细说明此响应中的“细微错误”注意事项:如果在访问仅存在于例如的元素之前使用WindowManager.DefaultDisplay.Rotation检查设备方向。纵向模式,FindViewById可以仍然返回null。在Xamarin上,Activity可以处于设备方向为纵向但尚未创建纵向视图元素的情况。如果您在切换活动后立即快速翻转设备,则会发生这种情况。 Activity的不一致版本将很快停止并使用正确的配置恢复,但它可以持续足够长的时间以使代码执行并获得NullReferenceException。这就是你应该检查FindViewById是否返回null的原因,而不仅仅是查看设备配置。
答案 1 :(得分:0)
1)创建一个名为drawable-land
的文件夹2)将您的xml文件复制并粘贴到此文件夹中,然后再次运行该应用并尝试更改方向。
答案 2 :(得分:0)
我不确定进行空检查是否会帮助其他人,毫无价值地说默认情况下应该声明空引用。此外,只有当视图不存在时,才应该在每次访问时加载视图...但这只是mymy2cents
在我的情况下,findViewByID返回一个空值,因为我在Activity中调用它,但视图属于层次结构。
所以你可以将MainMenu属性移动到片段,然后通过Activity中的片段访问它:
myFragment.MainMenu