Forum Xamarin.Forms

Android MasterDetailPage Renderer Doesn't Layout Second Pushed Page to Detail NavigationPage

pmhart83pmhart83 USMember ✭✭✭
edited February 2017 in Xamarin.Forms

I took the code I found for the Android MasterDetailPageRenderer in the Xamarin.Forms GitHub repo, and after some stubs / modifications got it to compile in my app. However, I am using a NavigationPage for the "detail" page and when I push a second page which has a custom renderer to this NavigationPage in Android, the screen is blank white because the size is 0x0 until I change orientations. I got a step further by creating a custom renderer for the NavigationPage which listens for a push event then calls Layout to forces the child views to layout. But now only some of the UI is displayed such as background colors until orientation is changed in the second pushed page.

My testing device:

Samsung Galaxy Tab Pro with v5.1.1 -- Note, a guy on stackoverflow said it worked for him using 6.0

I created a working example of this issue on my GitHub account which you can clone here:

https://github.com/XamarinMonkey/CustomMasterDetail

  • Build and run CustomMasterDetail.Droid (Notice the UI is a MasterDetailPage)

  • Tap any item

  • The bottom blue bar has no page numbers.

  • Rotate orientation the page numbers display.

  • Stop the build

  • Comment out the entire class "MainMasterDetailPageRenderer.cs"

  • Build / run the app

  • Tap any item

  • Page numbers are laid out to start with!!!

My best guess is that something is going wrong related to adding views through code rather than AXML? Been stuck on this for awhile so any help would be awesome!!!

See also:

http://stackoverflow.com/questions/42170659/xamarin-android-custom-masterdetailpage-not-calling-onlayout-when-page-pushed-to

Posts

  • pmhart83pmhart83 USMember ✭✭✭
    edited February 2017

    Anyone please, there is a working example above.

    Note: I have made some progress. The page numbers do layout in 5.1.1 if I call the following function in that view after subviews are added by code:

    private void relayout()
    {
      var w = MeasureSpec.MakeMeasureSpec(MeasuredWidth, MeasureSpecMode.Exactly);
      var h = MeasureSpec.MakeMeasureSpec(MeasuredHeight, MeasureSpecMode.Exactly);
      Measure(w, h);
      Layout(Left, Top, Right, Bottom);
    }
    

    My "real" project is more complex and I need to call / add relayout() to more than one sub-view. Could my issues somehow be related to VisualElementTracker? I'm not really familiar with the usage of this Forms class.

    **** The issue has to be adding a view programmatically in Android 5.1.1 to a native RelativeLayout after it is inflated and having to call relayout() each time this happens. Also maybe it relates to SendViewInitialized() which is not exposed.

  • JimmyGarridoJimmyGarrido USXamarin Team Xamurai

    Why are you copying over the MasterDetailPage renderer code from the source into your project instead of subclassing from Xamarin.Forms.Platform.Android.AppCompat.MasterDetailPageRenderer? By copying in the source code and modifying it so it builds in your project, you may be breaking or interfering with some of the setup Forms does for you which is resulting in this issue.

  • pmhart83pmhart83 USMember ✭✭✭
    edited February 2017

    @JimmyGarrido said:
    Why are you copying over the MasterDetailPage renderer code from the source into your project instead of subclassing from Xamarin.Forms.Platform.Android.AppCompat.MasterDetailPageRenderer? By copying in the source code and modifying it so it builds in your project, you may be breaking or interfering with some of the setup Forms does for you which is resulting in this issue.

    Because of private functions I can not change. We do not want the menu to stay locked open on a tablet but UpdateSplitViewLayout() is private. We dont want to use the default menu sizes, but those are also private / hard coded.

    I managed to fix a ton of bugs and gain more control doing this in iOS but iOS does not seem to have the issues with listening to layout like Android.

    On iOS there was a clear disconnect between what I expect IsPrestented to do and how it was working. The value of this var did not sync with the state of the UI and I managed to fix that with my own renderer.

    Why provide open source for things like the MasterDetailPageRenderer.cs but yet make everything private!!! If these where protected I could just put a blank function in UpdateSplitViewLayout() and save me a ton of head ache.

  • pmhart83pmhart83 USMember ✭✭✭
    edited February 2017

    After much hard work, I think I have this issue resolved!

    In my repo, if I modify the class MasterDetailContentNavigationPageRenderer.cs when there is a new element to do the following:

    ViewTreeObserver.GlobalLayout += handleGlobalLayout;

    Then in the handleGlobalLayout function call Measure / Layout on the renderer / viewgroup, it seems to work!!

    I have looked over the Android MasterDetailPageRenderer over and over. The only things I was missing was:

    • element.SendViewInitalized(this) - this just seems to set ContentDescription from what I saw
    • usages of ((Platform)_page.Platform)
    • usages of Device.Info

    I am looking at IsPlatformEnabled ... it might be what I needed but unable to test since it's again private.

  • JimmyGarridoJimmyGarrido USXamarin Team Xamurai

    I understand now and I'm glad you were able to get it to work!

    One thing I noticed was that the renderer and MasterDetailContainer source code you are using seems to be from the Xamarin.Forms.Platform.Android namespace, but your NavigationPage renderer and MainActivity are using AppCompat so this mismatch could be what's causing the issue. I would suggest using the source from the Xamarin.Forms.Platform.Android.AppCompat namespace instead.

  • pmhart83pmhart83 USMember ✭✭✭

    @JimmyGarrido said:
    I understand now and I'm glad you were able to get it to work!

    One thing I noticed was that the renderer and MasterDetailContainer source code you are using seems to be from the Xamarin.Forms.Platform.Android namespace, but your NavigationPage renderer and MainActivity are using AppCompat so this mismatch could be what's causing the issue. I would suggest using the source from the Xamarin.Forms.Platform.Android.AppCompat namespace instead.

    The AppCompat namespace seems to be for renderers. The elements that I am extending are ViewGroups. If there is another DrawerLayout or ViewGroup in a given namespace that could help!

  • pmhart83pmhart83 USMember ✭✭✭

    I updated my repo with my solution. Thanks for taking the time to help @JimmyGarrido

Sign In or Register to comment.