Forum Xamarin.Android

How to load a view in Master Detail Page, and activate it's child class C# code?

JKnottJKnott Member ✭✭✭
edited June 2019 in Xamarin.Android

Hello everyone! I hope there is a simple answer to this question because I have been beating my head against the wall for some time now over it, and am ready to move on from trying to achieve what I think should be a relatively easy process.... LOL
What I am trying to do, is populate a templated MasterDetail page from VS2019 with my own views from a project I worked on previously.

After some time I decided to go about loading the views into the master detail using this switch statement

      public bool OnNavigationItemSelected(IMenuItem item)
            {
                int id = item.ItemId;
                LinearLayout alt = FindViewById<LinearLayout>(Resource.Id.LLTarget);
                LayoutInflater layoutInflater = (LayoutInflater)BaseContext.GetSystemService(Context.LayoutInflaterService);
                View addView = null;

                if (id == Resource.Id.nav_add)
                {
                    alt.RemoveAllViewsInLayout();
                    addView = layoutInflater.Inflate(Resource.Layout.addDevice, null);
                }
                else if (id == Resource.Id.nav_list)
                {
                    alt.RemoveAllViewsInLayout();
                    addView = layoutInflater.Inflate(Resource.Layout.listDevices, null);
                }
              ... so on and so on...
                if (addView != null)
                    alt.AddView(addView);

                DrawerLayout drawer = FindViewById<DrawerLayout>(Resource.Id.drawer_layout);
                drawer.CloseDrawer(GravityCompat.Start);
                return true;
            }

The listDeviceand addDevice items are XAML pages, with associated view Classes that manipulate, and post-get data from the view,

Here is my problem,
While the code I have here, works beautifully to show the XAML pages. It will NOT call the onCreate() method for the class.
If I load the pages using SetContentView() or StartActivityForResult() I lose the ability to post the view as a sub page of the MasterDetail layout.

Here's a smple of my class layout

namespace TestApp2
{
    [Activity(Label = "@string/add_device")]
    public class AddDevice: Activity
    {
        private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();

        Spinner spinSubType;
        Button btnAdd;
        EditText ebModel;
        AutoCompleteTextView acMfg;
        EditText ebSerial;
        ImageButton btnPhoto;

        int _imgCount = 0;
        LinearLayout fsCon;
        List<DB.Photos> PhotoCollection = new List<DB.Photos>();
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
                logger.Info("Loading form addDevice");
                SetContentView(Resource.Layout.addDevice);
            try
            {
                logger.Info("Capturing controls from addDevice.axml");
                spinSubType= FindViewById<Spinner>(Resource.Id.typeSpinner);
                acMfg= FindViewById<AutoCompleteTextView>(Resource.Id.acMfg);
                btnAdd = FindViewById<Button>(Resource.Id.btnAdd);
                ebSerial = FindViewById<EditText>(Resource.Id.edSerial);
                btnPhoto = FindViewById<ImageButton>(Resource.Id.imageButton1);
                btnPhoto.SetImageResource(Resource.Drawable.ic_camera);
                btnPhoto.Click += BtnCamera_Click;
                fsCon = FindViewById<LinearLayout>(Resource.Id.fsCon);
            }
            catch (Exception e)
            { logger.Error(e.Message); }

            try
            {
                logger.Info("Populating spinner for types");
                LoadStyles(typeSpinner);
        LoadMfg(ebMfg);
            }
            catch (Exception ex)
            { logger.Error(ex); }

            btnAdd.Click += BtnAdd_Click;
            typeSpinner.ItemSelected += new EventHandler<AdapterView.ItemSelectedEventArgs>(Spinner_ItemSelected);
        }
}

I know this has to be something insanely easy and simple I am overlooking, probably expecting it to be overly complex and not seeing the obvious simple answer. Or it is somewhat complex, and my google kungfu is too weak...
At any rate, any advice, tips, or ideas would be MOST appreciated!

Cheers!

Best Answers

Answers

  • jezhjezh Member, Xamarin Team Xamurai

    Could you please post a basic demo so that we can test with it ?

  • JKnottJKnott Member ✭✭✭

    Here's a sample project I've created to demonstrate what's going on.
    I cam create the graphical aspect of the layout (named layout in the project), But I cannot get the spinner on the page populated, because the class associated with it is never being instantiated...

    Demo.7z 426.7K
  • JKnottJKnott Member ✭✭✭

    That did it! I was wondering if it would need to be fragments... I'm really new to android and Xamarin, so this has been an interesting journey so far, thank god for communities like this!
    I've got a couple oddities going on that I need to drill down, (namely the onclick listener for the spinner is firing no matter what) but that will probably be another post down the road.
    Thanks again for the help!
    Cheers!

  • jezhjezh Member, Xamarin Team Xamurai

    Glad to help. Happy coding! :)

  • JKnottJKnott Member ✭✭✭
    edited July 2019

    Here's a follow up question if you don't mind.
    Is there an easy way for me to access member fields within the fragment class?
    I am trying to make model where a specific record can be called up by setting an interger within the spinnerfragment class..
    Running through the debugger I can see the RecordID field listed as one of the non-public members. so I set it to public, and it will show if I use it as the type of SpinnerFragment, but when as type var it will not show me the member fields.
    If I try to use the class in the code IE
    SpinnerFragment fragment = SpinnerFragmen.NewInstance();

    I get errors saying 'cannot convert type Android.Fragment to Demo.SpinnerFragment'
    Is there a member function I can call? or an overloaded function I can cast?

    pseudo code would be something like

         else if (id == Resource.Id.nav_gallery)
                {
                    //Set the content of the LinearLayout on the main page to our target page
                    var fragment = SpinnerFragment.NewInstance();
                fragment.RecordID=3;
                    var fragmentManager = this.FragmentManager;
                    var ft = fragmentManager.BeginTransaction();
                    ft.Replace(Resource.Id.LLTarget, fragment);
                    ft.Commit();
                }
    

    The RecordID is set in the fragment parent class

        public class SpinnerFragment : Fragment
        {
            int RecordID = -1;
            public override void OnCreate(Bundle savedInstanceState)
            {
                base.OnCreate(savedInstanceState);
    
                // Create your fragment here
            }
    
            public static Fragment NewInstance()
            {
                Fragment fragment = new SpinnerFragment();
                return fragment;
            }
    ...etc etc....
        }
    

    I am trying to use this style of loading the page to reuse the data entry page for the item as a view page for an existing item... more or less something along the lines of...
    if (RecordID ==-1)
    ...New record, show blank fields and add record to db...
    else if (RecordID != -1)
    ...Look up RecordID from DB and fill the form so record can be updated...

    I can start a new thread if needed...
    Thanks again!

  • jezhjezh Member, Xamarin Team Xamurai
    edited July 2019

    @JKnott Do you want to pass data to SpinnerFragment ?

  • JKnottJKnott Member ✭✭✭
    Yes, I will then add logic to query the original record from that passed data
  • JKnottJKnott Member ✭✭✭

    @jezh I could be completely missing the function of fragments, and confusing them with actions... I'm extremely new to Android, and it's especially dangerous since I was a C++ coder in the past, and am used to being in total control of what I am doing in code. C# has been a godsend since I am so out of practice, and it makes coding so much easier, but I think I have a false sense of stability. I get the impression that I am getting stuck in the whole "Do UI stuff here, and code behind over there"

  • JKnottJKnott Member ✭✭✭

    @jezh Looks like I need to do it in sending a "bundle" I'll give that a shot and update if it worked.

  • JKnottJKnott Member ✭✭✭

    @jezh Thanks! That's actually a little more succinct than the method I found to do it,
    Perfect!
    Thanks again!

Sign In or Register to comment.