8

I am trying to make an android app using Xamarin so C#. I made two layouts and in each one of them I made 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 when I start the app I get this errror: System.NullReferenceException has been thrown.Object reference not set to an instance of an object. Any advice or better idea?

peterh
  • 11,875
  • 18
  • 85
  • 108
user3836246
  • 357
  • 2
  • 5
  • 13
  • which line throws the exception? – Federico Berasategui Aug 08 '14 at 18:26
  • As a side comment, you should get acquainted with C# and OOP in general before trying to develop mobile apps using complex frameworks such as Xamarin. See [What is a NullReferenceException and how do I fix it?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it). – Federico Berasategui Aug 08 '14 at 18:27
  • this.FindViewById – user3836246 Aug 08 '14 at 18:28
  • Either `Resource` is `null`, or FindByViewId returned a `null` object. Check it with your debugger. Assign the result of `FindViewById` to its own variable if you have to, and check it for `null` before dereferencing it. – Robert Harvey Aug 08 '14 at 18:31
  • @RobertHarvey `Resource` in Xamarin.Android is a designer-generated class similar to `Resources` in winforms or WPF. It is a class reference, not an object reference so it can't be null. – Federico Berasategui Aug 08 '14 at 18:34
  • Then it must be the other thing I mentioned, right? – Robert Harvey Aug 08 '14 at 18:36
  • @RobertHarvey yes, but I wanted to have the opportunity to explain to the OP that `FindViewById – Federico Berasategui Aug 08 '14 at 18:37
  • So this.SetContentView(Resource.Layout.Main); returns null? – user3836246 Aug 08 '14 at 18:40
  • If is the button should apear this error on the down line too. – user3836246 Aug 08 '14 at 18:42
  • Can you share the XML of both the layouts, i.e. Main and Main2? – Ahmed Salman Tahir Aug 08 '14 at 18:46
  • @Ahmed Salman Tahir Look here: http://txs.io/2Ipb. – user3836246 Aug 08 '14 at 18:50
  • This is a duplicate of http://stackoverflow.com/questions/25203546/error-java-lang-nosuchmethodexception . The layout XML is there as well as I wrote it as an example. That code compiles and runs fine. – Frank Aug 09 '14 at 06:27
  • @Frank Sorry but I was hurriedly.Anyway,thank you! I solve my problem.I made two activity with two layouts and I navigate between them with help of StartActivity command. – user3836246 Aug 09 '14 at 06:47

3 Answers3

12

You are setting Main as the layout for your activity and then in the following lines of code you are asking to find a button named Back at runtime which is not part of this layout. This means 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 a System.NullReferenceException.

EDIT:

In view of the comments, here is what you should do to achieve what you are looking for:

Create two different activities (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));
    }
Ahmed Salman Tahir
  • 1,783
  • 1
  • 17
  • 26
2

Since it just happened to me and almost drove me up the wall, here is yet another way FindViewById can return null and how to fix it. Probably not a mistake a more experienced Android developer is likely to make, but still, it might prevent some frustration for someone like 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 FindViewById call in OnCreate of my main view suddenly returned null when run on a physical device

  • It turns out I had just run some updates through the Android SDK Manager, which introduced a new Android Version (in this case Android 7) to my system, and my device simply did not have that version installed yet.

The solution

  • In the properties of my Android project, the "Compile using Android version" drop down was set to "Use Latest Platform", which now was pointing to the newly installed Android 7 -- simply setting it to the version of Android running on my test device (in my case 6) and recompiling fixed the null return value.

TL;DR Check that the version of Android you are compiling against is in fact supported by the device you are testing on.

jcb
  • 382
  • 3
  • 17
1

You're getting a NullReferenceException because this code:

FindViewById<Button>(Resource.Id.BackButton)

returns null. This may be caused by either:

  • 1 - You didn't properly annotate the Button with an android:id attribute, like so:

    <Button ...
    android:id="@+id/BackButton"/>
    

--OR--

  • 2 - that Button isn't defined on the Main layout and therefore it isn't part of the Activity's current view. Therefore the FindViewById() method can't find it. Your intended approach to switch screens isn't supported on Android.

    Which leads to a longer explanation about the Correct way to "switch screens" on Android: navigating between simple activities

Try one of these solutions.

Community
  • 1
  • 1
Federico Berasategui
  • 43,562
  • 11
  • 100
  • 154
  • I don't think is one of this. Look here my layouts of Main and Main2: http://en.textsave.org/2Ipb – user3836246 Aug 08 '14 at 18:54
  • I think i disagree with number 1, it will return error if it does have a different id name. `Resource.Id` will not recognize it. – newbieguy Dec 21 '17 at 21:49