Xamarin FindViewById returns null
Hi guys, I need a little advice. I am trying to make an Android app using Xamarin so C #. I made two layouts and in each one I made the tow buttons to navigate between them. I tried like this:
using System;
using Android.App;
using Android.OS;
using Android.Views;
using Android.Widget;
namespace Example
{
[Activity(Label = "Example", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
this.SetContentView(Resource.Layout.Main);
this.FindViewById<Button>(Resource.Id.ForwardButton).Click += this.Forward;
this.FindViewById<Button>(Resource.Id.BackButton).Click += this.Back;
}
public void Forward(object sender, EventArgs e)
{
this.SetContentView(Resource.Layout.Main2);
}
public void Back(object sender, EventArgs e)
{
this.SetContentView(Resource.Layout.Main);
}
}
}
But every time I run the application I get this message: System.NullReferenceException fixed. An object reference is not set on an object instance. Any advice or a better idea?
source to share
You set Main
as a layout for your activity, and then in the following lines of code you ask to find a named button Back
at runtime that is not part of that layout. This means that the following line will return null:
FindViewById<Button>(Resource.Id.BackButton)
Now if you do FindViewById<Button>(Resource.Id.BackButton).Click
, you will definitely get it System.NullReferenceException
.
EDIT:
In relation to the comments, here's what you need to do to achieve what you're looking for:
Create two different actions ( Main1
and Main2
). In Main1
you do:
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
this.SetContentView(Resource.Layout.Main);
this.FindViewById<Button>(Resource.Id.ForwardButton).Click += this.Forward;
}
public void Forward(object sender, EventArgs e)
{
this.StartActivity (typeof(Main2));
}
Then in Main2
you do:
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
this.SetContentView(Resource.Layout.Main2);
this.FindViewById<Button>(Resource.Id.BackButton).Click += this.Back;
}
public void Back(object sender, EventArgs e)
{
this.StartActivity (typeof(Main));
}
source to share
Since this happened to me and almost led me to the wall, here's another way FindViewById
to get it back null
and how to fix it. This is probably not a mistake that a more experienced Android developer is more likely to make, but it might still prevent some frustration for the likes of me in the future.
My situation
-
My control was in the correct view (not a fragment), the ID was assigned correctly, everything used to work just a couple of days ago when I last worked on the project.
-
After building the project, the very first call
FindViewById
toOnCreate
my main view returned unexpectedlynull
when running on a physical device -
It turned out that I had just run some updates via the Android SDK Manager which introduced a new version of Android (in this case Android 7) for my system, and my device just didn't have the version installed.
Decision
- In the properties of my Android project, the Compile with Android dropdown was set to Use Latest Platform, which now pointed to a newly installed Android 7 - just setting it to the Android version on my test device (6 in my case) and recompiling the return value is fixed
null
.
TL; DR Make sure the Android version you are compiling is actually supported by the device you are testing on.
source to share
You get NullReferenceException
because this code:
FindViewById<Button>(Resource.Id.BackButton)
returns null
. This can be caused by either:
-
1 - You have commented incorrectly
Button
with an attributeandroid:id
like:<Button ... android:id="@+id/BackButton"/>
- OR -
-
2 - This button is not defined on the layout
Main
and therefore is not part of the current Activity view. Therefore, the methodFindViewById()
cannot find it. Your approach to toggle screens is not supported on Android.This leads to a more detailed explanation of the correct way to "switch screens" on Android: moving between simple actions
Try one of these solutions.
source to share