alexrainman / SegmentedControl

MIT License
86 stars 38 forks source link

Late instantiation of the RadioGroup control in the Android renderer fails to display #45

Closed JosHuybrighs closed 7 years ago

JosHuybrighs commented 7 years ago

My app is using a TabbedPage where each of the child pages are creating their content at the moment the page is selected (UI virtualization). The implementation of this concept is done by my TabbedPageExt plugin. https://www.nuget.org/packages/CwwOnline.TabbedPageExt.Xamarin/.

It works basically as follows:

The issue now is that when a child page contains a SegmentedControl the plugin displays correctly on iOS but not on Android; the RadioGroup and buttons or not displayed when the user selects a page containing a SegmentedControl. I took your code and looked at it and it seems that the reason for the error is in the delayed setting of the RadioGroup control. As it is now, the control is set when a size-changed event occurs on the SegmentedControl object. I modified your code and set the native control immediately in ElementChanged (where it should be as per xamarin guidelines) and that solves it.

Any reason why it is not done in ElementChanged?

alexrainman commented 7 years ago

Where is Xamarin Guidelines says it should be done in ElementChanged?

alexrainman commented 7 years ago

And how to reproduce this because i have it working on a TabbedPage without any issues.

alexrainman commented 7 years ago

This issue must be related to the other plugin you are using.

JosHuybrighs commented 7 years ago

Alex,

It doesn't say it explicitly but (as written in https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/custom-renderer/introduction/) xamarin mentions it as the method in which the native control 'often' is instantiated. In all of their example renderers the control gets instantiated there.

Anyhow, I have modified your Demo project (which I got from Github) to try to find in which circumstance it goes wrong. As I expected the issue where the radiogroup control doesn't appear comes up when the SegmentedControl is not defined immediately when the ContentPage is created but later, e.g. as the result of some user action, or (as in my TabbedPageExt plugin) when the SegmentedControl is created outside of the page). You can easily test this (as I did) with a 'normal' TabbedPage where there is a button that lets the user create/destroy the SegmentedControl.

I did the following in your Demo project:

  1. Created a DynSCPage.xaml:

<?xml version="1.0" encoding="utf-8" ?> <ContentPage x:Class="Demo.DynSCPage" xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:controls="clr-namespace:SegmentedControl.FormsPlugin.Abstractions;assembly=SegmentedControl.FormsPlugin.Abstractions"> <StackLayout Padding="12" Spacing="12">

<StackLayout x:Name="SegContent" />
<Button Text="Toggle SegmentedControl" Clicked="Button_Clicked"/>

  1. DynSCPage.xaml.cs: public partial class DynSCPage : ContentPage { SegmentedControl.FormsPlugin.Abstractions.SegmentedControl _segControl;

    public DynSCPage() { InitializeComponent(); Title = "Inserted SC"; } void SegControl_ValueChanged(object sender, EventArgs e) { this.SegContent.Children.Clear(); switch (_segControl.SelectedSegment) { case 0: SegContent.Children.Add(new Label() { Text = "Items tab selected" }); break; case 1: SegContent.Children.Add(new Label() { Text = "Notes tab selected" }); break; } }

    private void Button_Clicked(object sender, EventArgs e) { if (_segControl == null) { _segControl = new SegmentedControl.FormsPlugin.Abstractions.SegmentedControl(); _segControl.Children.Add(new SegmentedControl.FormsPlugin.Abstractions.SegmentedControlOption() { Text = "Items" }); _segControl.Children.Add(new SegmentedControl.FormsPlugin.Abstractions.SegmentedControlOption() { Text = "Notes" }); _segControl.ValueChanged += SegControl_ValueChanged; segContainer.Children.Add(_segControl); } else { segContainer.Children.Remove(_segControl); _segControl = null; } } }

  2. Instantiated 2 TabbedPages in App.xaml.cs:

MainPage = new TabbedPage { Children = { new DemoPage(), new DynSCPage() } };

Doing the above indeed shows the problem where the SegmentedControl doesn't show in SynSCPage when the user clicks the button.

As I mentioned before, when I move the instantiation of the radiogroup to 'OnElementChanged' eveything is OK.

Hope this helps?

Best regards, Jos


Van: Alex Rainman notifications@github.com Verzonden: vrijdag 1 september 2017 17:36 Aan: alexrainman/SegmentedControl CC: Jos Huybrighs; Author Onderwerp: Re: [alexrainman/SegmentedControl] Late instantiation of the RadioGroup control in the Android renderer fails to display (#45)

Where is Xamarin Guidelines says it should be done in ElementChanged?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/alexrainman/SegmentedControl/issues/45#issuecomment-326612752, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AAXMpGD_LfnfNtrGpo0T5EAE03BxIAynks5seCR5gaJpZM4OnX7w.

alexrainman commented 7 years ago

I have another control, the CarouselView, that uses the same init technique and its about to be included in Xamarin.Forms 3 release :)

Try the last release, i fixed this issue. Thanks

JosHuybrighs commented 7 years ago

Sorry to say but the issue is still in the latest release. You can easily check this by modifying your DemoPage in such a way that the SegmentedControl is not statically, upfront defined, but is instantiated when the user presses a button in DemoPage. The issue also comes up when there is no TabbedPage at all. You can test this by simply assigning the above listed DynSCPage to MainPage.

As I see it, the 'size_changed' event in the renderer doesn't occur in case you want to dynamically insert a SegmentedControl to the StackLayout of a ContentPage. With dynamically I mean: when the ContentPage is open and the user creates the control by pressing a button on the page.

Don't understand what you mean with CarouselView?


Van: Alex Rainman notifications@github.com Verzonden: zondag 3 september 2017 15:34 Aan: alexrainman/SegmentedControl CC: Jos Huybrighs; Author Onderwerp: Re: [alexrainman/SegmentedControl] Late instantiation of the RadioGroup control in the Android renderer fails to display (#45)

I have another control, the CarouselView, that uses the same init technique and its about to be included in Xamarin.Forms 3 release :)

Try the last release, i fixed this issue. Thanks

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/alexrainman/SegmentedControl/issues/45#issuecomment-326805317, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AAXMpI1AjKAXWzUIHmnK2b3_DHoSrQelks5seqrvgaJpZM4OnX7w.