4

Preview: Xamarin.Forms Embedding

 3 years ago
source link: https://forums.xamarin.com/discussion/96889/preview-xamarin-forms-embedding
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

ForumXamarin.Forms

We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

Preview: Xamarin.Forms Embedding

Starting a new thread to host feedback for this preview.

Blog kicking off 3.0 and our Build 2017 announcements round-up: https://blog.xamarin.com/glimpse-future-xamarin-forms-3-0/

NuGet Feed: https://www.myget.org/F/xamarinforms-dev/api/v3/index.json
Weather App source: https://github.com/davidortinau/build2017-new-in-xamarin-forms

  • Lots of new features. Hurray.

    What about existing bugs? Bringing Xamarin.Forms to native apps is cool and all, but if the year-old bugzilla tickets still aren't resolved aren't you just pushing problems out

    in more ways, on more platforms, and faster than ever before.

    Styling: we’re polishing up a CSS-inspired styling implementation that’s requested often.

    Really? Requested by whom? I was active on that thread and the people that wanted it were web coders that had no application experience. All the experienced program developers kept saying it was pointless and confusing to introduce another styling system and should at least happen AFTER all the bugs in the current style system are fixed.

    Is this new Xamarin.Form 3.0 going to fill in the FUNCTIONALITY gaps?
    1. Multibinding?
    2. Problems with static resources?
    3. Binding to nulls not going to converters?
    4. ...

    I guess I'm asking if it will at least bring Xamarin XAML up to par with WPF XAML so the people with a decade of XAML/MVVM experience can stop feeling crippled and limited by comparrison?

  • I can't wait for this to be live! So many of our apps at the moment cannot be properly planned and ported over to Xamarin as customers are always wanting more features on the native solutions first. This I hope will make it that little bit easier to plan and migrate across our AGILE sprints :smile:

    Any news on whether it looks technically feasible to get Forms embedding into the non-windows native implementations yet? i.e Java, Swift, Obj-C...
    It would be cool to be able to hold back some of my existing projects at the moment in favour of this.

    Great presentation and keep up the good work burning through that Bugzilla!

  • @ClintStLaurent said:
    Really? Requested by whom? I was active on that thread and the people that wanted it were web coders that had no application experience. All the experienced program developers kept saying it was pointless and confusing to introduce another styling system and should at least happen AFTER all the bugs in the current style system are fixed.

    On the other thread discussing CSS layouts, @DavidOrtinau clearly indicated that it's completely optional. You can choose to ignore its existence entirely if you want to.

    As a developer, I'm sure you can empathize that not all decisions are purely pragmatic ones.

    I'd imagine someone in product management was tasked with increasing the Xamarin user-base and making layouts more friendly to people that don't typically develop mobile apps.

    The obvious answer: Make it easier for web developers to get a "native" app that they can put in an app store. (Yes, Google heavily promotes PWAs on Android to the extent that they're treated similarly to standard Android apps and PWAs are even linked in the Windows Store now... But those people might still want access to more device functionality.)

    Ultimately, as long as the new CSS layouts don't end up resulting in significant development resources being redirected into fixing issues that they might introduce... I think having more options is great.

    The easier it is for people to become Xamarin.Forms developers, the more people will try it out, and thus Microsoft may ultimately allocate even more resources to Xamarin.Forms development.

    It really seems like a win-win for developers, should it actually succeed in attracting new Xamarin devs.

    @ClintStLaurent said:
    I guess I'm asking if it will at least bring Xamarin XAML up to par with WPF XAML so the people with a decade of XAML/MVVM experience can stop feeling crippled and limited by comparrison?

    As someone that still has to support a .NET CF 3.5 application, I definitely know about using a limited subset of features that you've grown accustomed to. However, any good developer should be able to learn about those limitations and persevere anyway.

    Xamarin.Forms is also open-source, so you could always take it upon yourself to add whatever functionality that you're missing from WPF and submit a PR: https://github.com/xamarin/Xamarin.Forms

    Edit: Just noticed this in the article:

    Introducing XAML Standard

    As announced at Microsoft Build 2017, we’re collaborating with the Windows division on XAML Standard, a way to share XAML as an asset. Xamarin.Forms will fully support XAML Standard and take you to every platform you need to be on.

    Frameworks that support XAML Standard will be able to share common XAML based UI definitions. Our goal is for the first version, XAML Standard 1.0, to be available later this year.

    So it seems likely that they're probably going to focus on more XAML features later this year.

  • @ClintStLaurent lots of activity last 2 weeks on bugzilla and github. All bug fixing. Closed roughly 10%.

    I hope you're raising those XAML issues on the XAML Standard GitHub.

    I personally talk to developers and customers multiple times a week on the phone and online. I get loads of email. Its all taken into account and we are truly about enabling devs to do more. CSS is an example. Embedding is another. Use it. Or don't. Your call.

    @RyanDixon it's still quite early. Shoot me an email and I can perhaps help inform your planning of those projects. [email protected] Thx for the encouragement!

    @ChrisBoyd very insightful comments. ;)

    ---

    Posted a slightly deeper dive into Embedding on the blog today.

    https://blog.xamarin.com/unleashed-embedding-xamarin-forms-in-xamarin-native/

    And I noticed @jsuarezruiz also blogged recently, and once I translate it I'll know if he likes it or not. :)

    https://geeks.ms/jsuarez/2017/05/22/xamarin-forms-forms-embedding/
  • @DavidOrtinau Yes. I did some tests with the current Xamarin.Forms version where you have to create several pipes (Application, WindowsPage, etc.) to do something similar to Forms Embedding and with Xamarin.Forms 3.0.
    In Xamarin.Forms 3.0 with PageExtensions is really easy to use. The performance (time from the start of the conversion of the ContentPage to the native element until the rendering) is also better.
    I find it very interesting!.

  • David,

    Thanks for the blog on embedding XF in native apps. The idea of mixing Xamarin Native with Xamarin.Forms makes a lot of sense to me particularly if you need to convert an existing Xamarin app to XF; it allows you to take an iterative approach rather than needing to port the entire app.

    Earlier this year I was working with a client to develop a prototype to demonstrate exactly how we could iteratively convert their Xamarin.Android / Xamarin.iOS / MvvmCross apps to XF but we were advised by Xamarin that it would not work. We shared progress we had made in developing the prototype loosely following an article by Michael Ridland (http://www.michaelridland.com/xamarin/mixing-xamarin-forms-mvvmcross-nativeviews/) and Xamarin responded by saying they would not be able to support us with any issues we had and the XF team did not have this capability identified as something XF would support. At that point I had to advise the customer to abandon the idea which meant abandoning XF because they did not have time to convert the entire app all at once.

    Do you think the capability to embed XF pages in native apps will become a core capability? Does the XF team see the value in this capability?

  • I am testing this new embedding feature out. Exciting!

  • Got it working now - cool, showing a ContentPage - but how to perform navigation, when I for example click a button ?

    I took some from the samples

        async void OnNextPageButtonClicked(object sender, EventArgs e)
        {
            await Navigation.PushAsync(new CreateLogin());
        }

    But when I click on the button, I get this error message :

    "PushAsync is not supported globally on iOS, pleas us a NavigationPage"

    Is that possible when using embedding ?

  • @DavidOrtinau said:
    @ClintStLaurent lots of activity last 2 weeks on bugzilla and github. All bug fixing. Closed roughly 10%.

    I hope you're raising those XAML issues on the XAML Standard GitHub.

    Just to clarify... These issues were raised many many times... they have been noted here... in the Forms.Evolution thread... as well as bugzilla... Are you saying existing and documented issues aren't automatically carried over to the next body of work-In this case XAML Standard? I would have thought that the folks working on XAML standard would take the existing issues into account as part of their roadmap. Otherwise if its its create from scratch again: Who know what will and won't be addressed?

    But okay... "Raise those issues on XAML Standard GitHub" that's the instruction you're giving to people. Got it. Thanks!

  • @ClintStLaurent said:

    Just to clarify... These issues were raised many many times... they have been noted here... in the Forms.Evolution thread... as well as bugzilla... Are you saying existing and documented issues aren't automatically carried over to the next body of work-In this case XAML Standard? I would have thought that the folks working on XAML standard would take the existing issues into account as part of their roadmap. Otherwise if its its create from scratch again: Who know what will and won't be addressed?

    But okay... "Raise those issues on XAML Standard GitHub" that's the instruction you're giving to people. Got it. Thanks!

    This is a very important point Clint highlights, @DavidOrtinau could you clarify what issues we should log in bugzilla (such as the issues I highlighted in the UWP in the 2.3.4 thread), should XAML only issues be logged in .netstandard github?

  • @OlegPrymak said:
    @DavidOrtinau Do you support V4 fragments?

    Putting the answer from twitter on here so just so it's easier for people to find: as of right now, only plain old Fragments are supported; V4 fragments are on the list for that feature when 3.0 hits.

  • I am very confused about all this. Read the article. Listened to the Xamarin Podcast about this. This is new?

    This example has been around for a long time: https://github.com/xamarin/xamarin-forms-samples/tree/master/Native2Forms

    I have been embedding a xamarin forms page in my native apps for a long time already, on iOS for example:

    var page = new XamFormPage ();
    var navVC = new NavigationPage (page).CreateViewController ();
    navVC.ModalPresentationStyle = UIModalPresentationStyle.FormSheet;
    presentFrom.PresentViewController (navVC, true, null);

    This has been running with older stable forms versions for over a year. So what is different / new in Xamarin forms 3.0?

  • @SjoerdvanNoort said:
    I am very confused about all this. Read the article. Listened to the Xamarin Podcast about this. This is new?

    This example has been around for a long time: https://github.com/xamarin/xamarin-forms-samples/tree/master/Native2Forms

    I have been embedding a xamarin forms page in my native apps for a long time already, on iOS for example:

    var page = new XamFormPage ();
    var navVC = new NavigationPage (page).CreateViewController ();
    navVC.ModalPresentationStyle = UIModalPresentationStyle.FormSheet;
    presentFrom.PresentViewController (navVC, true, null);

    This has been running with older stable forms versions for over a year. So what is different / new in Xamarin forms 3.0?

    From an iOS perspective, none of this is new. It's basically exactly what you're seeing in that GitHub repo.

    From an Android perspective, it's very different. The version in that repo works by starting a new Activity. The stuff in 3.0 uses Fragments, so you can embed XF pages without starting a new Activity.

    And from a Windows perspective, the whole thing is brand new; this capability didn't exist at all previously.

    (And I imagine that we'll also be bringing the capability to macOS as that comes out of preview mode.)

  • Ah thank you @EZHart. In can confirm that it already works on the macOS preview. Although XF for macOS still needs some polish. Looking forward to the stable release.

  • @JulioCamps said:
    HI, in the sample you show how navigate from native ios to forms using CreateViewController.
    BUt my question is how navigate from inside a Forms ContentPage to a native ios viewcontroller?? Forms Navigation.PushAsync only support a Page parameter :(

    What you're asking for isn't currently possible in Forms; there is no option to push a UIViewController onto the XF page stack.

    If you have some iOS content that you want to use within a XF application, there are some other options:

    • you could create a custom renderer which renders using your iOS control
    • you could use the native embedding features to host your iOS control in a Xamarin Forms page
  • @NMackay said:
    This is a very important point Clint highlights, @DavidOrtinau could you clarify what issues we should log in bugzilla (such as the issues I highlighted in the UWP in the 2.3.4 thread), should XAML only issues be logged in .netstandard github?

    Sorry, I'm not trying to create confusion.

    Any issues related to Xamarin.Forms should be logged in Bugzilla with a project that demonstrates the issue.

    Enhancement requests to Xamarin.Forms may be logged in Bugzilla. If you want Xamarin.Forms XAML to implement x,y,z feature you like from WPF, for example. If you're ready to go a step further by proposing an implementation and/or offering to take on the task, then post in the Evolution forum.

    If the request is "I want to use the same XAML on all platforms that support it without making changes" and so it needs to do "x,y,z", or how XAML should evolve together between Xamarin.Forms, UWP, etc. then that conversation/feedback is useful on the XAML Standard GitHub.

  • @JulioCamps, that's cool.

    If you're going to end up using that inside Android or any other platform, I would suggest making that code platform specific. You could use ifdef and conditionally compile it.

    Myself, I would either adopt an existing framework that has a cross platform navigation controller, or implement my own navigation service to isolate these implementations on each platform.

  • I'm currently trying to use this to create a popover in iOS:

            void ShowPopup(Xamarin.Forms.View view, Xamarin.Forms.Page page)
            {
                var popoverContent = page.CreateViewController();
                popoverContent.ModalPresentationStyle = UIModalPresentationStyle.Popover;
                var popover = popoverContent.PopoverPresentationController;
                popoverContent.PreferredContentSize = new CGSize(300, 300);
                popover.Delegate = popoverDelegate;
                popover.SourceView = this.View;
                popover.SourceRect = view.Bounds.ToRectangleF();
                this.PresentViewController(popoverContent, true, null);
            }

    Where view is the button that was clicked to initiate the popover.

    When page is created fresh each time, I get a "Static Resources" error where it cannot resolve the background color whenever I try to access the popup a second time (after dismissing the initial popover).

    If I try to store the Page itself to a property and just use that same property to call the ShowPopup, then it displays a blank view controller every time after dismissing the initial popover.

  • So I ended up storing the UIViewController for the popoverContent inside the Renderer for testing purposes and was able to repeatedly show the popover without any issues.

    However, it'd be nice to be able to modify the page itself and be able to get those reflected into the UIViewController as well as have a command more like GetRenderer() that would return the UIViewController that had been previously generated for that Page.

    As it is, once you've generated the UIViewController from the Page, it seems like you have to make any changes directly with the UIViewController and not the Page itself.

    Moreover, it still seems strange that I get exceptions (related to not being able to resolve a color resource from StaticResources) if I try to use new MyPage().CreateViewController() a second time.

  • Thanks @ChrisBoyd.

    StaticResources definitely needs work. Good feedback on the expected behavior of Page and the native view.

  • Hi @DavidOrtinau

    While you are answering matters of native embedding, do you know a way to set the Layout_Height of a native android fragment? Without being able to set this in the XAML it is never passed to the constructor of the fragment so no size parameters are assigned to a native fragment or passed to the children via the constructor: Leaving all the children with a size of zero by zero.

            <views:View x:Name="mapWrap"
                        Grid.Row="2"
                        Grid.RowSpan="3"
                        Grid.Column="0"
                        Grid.ColumnSpan="3"
                        x:Arguments="{x:Static androidForms:Forms.Context}">
    
                <mappy:HereMapFrag x:Arguments="{x:Static androidForms:Forms.Context}">
                    <!--  Need a way to set the Layout_Height and Layout_Width from here  -->
                </mappy:HereMapFrag>
            </views:View>
            <!--#endregion Android only native controls-->

    @JGoldberger Has been trying hard to help both in a thread here and through the Microsoft MSDN Enterprise ticket we opened for this - and to his credit he has been doing his best to help - but even he admits that native embedding is not something he has a lot of experience with.

    In native Android Java one would do this:

    yqrwxvxk50cc.png

    What's the Xamarin syntax for doing this? You've written official blog tutorials for doing this; If anyone knows I figure it should be you.

  • @ClintStLaurent I went over this with @EZHart and he generously whipped up some code samples for a few options that might work for your situation.

    https://github.com/hartez/PCLNativeEmbeddingAdjustment

  • @DavidOrtinau and @EZHart
    I am very very grateful for the time and effort in producing that solution.

    I do not however see anyplace where the native parameter of Layout_Width or Layout_Height is passed to a native Fragment.

    @EZHart markup:

            <StackLayout x:Name="Layout">
    
                <!-- Native controls. In this project we've got a mechanism set up to ship the native Android TextView 
                out to the native Android project for some modifications -->
                <ios:UILabel Text="Native Text" View.HorizontalOptions="Start"/>
                <androidWidget:TextView Text="Native Text" x:Arguments="{x:Static formsandroid:Forms.Context}" />
                <win:TextBlock Text="Native Text"/>
    
                <!-- Placeholder for a native control to be added later -->
                <ContentView x:Name="Placeholder"></ContentView>
            </StackLayout>

    Produces a native Widget of TextView. That's not a problem because a Widget doesn't require the Layout parameter.
    I've done the same thing for testing, with no problem showing a native Checkbox and RatingsBar

        <Grid HorizontalOptions="FillAndExpand"
              VerticalOptions="FillAndExpand"
              BackgroundColor="Gray"
              HeightRequest="600"
              WidthRequest="800">
            <Grid.RowDefinitions>
                <RowDefinition Height="100" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="100" />
                <RowDefinition Height="100" />
                <RowDefinition Height="100" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="100" />
                <ColumnDefinition Width="100" />
                <ColumnDefinition Width="100" />
                <ColumnDefinition Width="100" />
                <ColumnDefinition Width="100" />
                <ColumnDefinition Width="100" />
                <ColumnDefinition Width="100" />
                <ColumnDefinition Width="100" />
            </Grid.ColumnDefinitions>
    
            <Label Grid.Row="0"
                   Grid.Column="0"
                   Grid.ColumnSpan="8"
                   Margin="0,0,20,0"
                   HorizontalOptions="Center"
                   FontSize="40"
                   HorizontalTextAlignment="Center"
                   TextColor="Black">
                <!--  This is a XF agnostic Label control  -->
                Native UI control embedding example (PCL)
            </Label>
    
            <!--#region Android only native controls-->
            <!--  When intellisense reports that it can't resolve Forms.Context ignore that. That's intellisense/ReSharper, not a real error  -->
            <widget:CheckBox Grid.Row="1"
                             Grid.Column="0"
                             x:Arguments="{x:Static androidForms:Forms.Context}"
                             Checked="True" />
    
            <widget:RatingBar Grid.Row="1"
                              Grid.Column="1"
                              Grid.ColumnSpan="2"
                              x:Arguments="{x:Static androidForms:Forms.Context}" />
    
            <views:View x:Name="mapWrap"
                        Grid.Row="2"
                        Grid.RowSpan="3"
                        Grid.Column="0"
                        Grid.ColumnSpan="3"
                        x:Arguments="{x:Static androidForms:Forms.Context}">
    
                <mappy:HereMapFrag x:Arguments="{x:Static androidForms:Forms.Context}">
                    <!--  When intellisense reports that it can't resolve mappy:HereMapFrag ignore that. That's intellisense/ReSharper, not a real error  -->
                    <!--  Need a way to set the Layout_Height and Layout_Width from here  -->
                </mappy:HereMapFrag>
            </views:View>
            <!--#endregion Android only native controls-->
    
        </Grid>
    rgm3d3x3kka7.png

    Where things go sideways is when you want to place a Fragment. That's where you have to set the two Layout parameters

    z6hc52u2ugwk.png
  • @DavidOrtinau @EZHart
    Uh... FYI... My sample solution was sent to @JGoldberger via Microsoft Secure File exchange.
    I would assume there is a way of sharing that internally if you want to see it.
    I don't want to put it on an unsecured repository because our assigned product keys for the HERE api are in the code. I trust MS to not make use of them, but can't release that into the wild. B)

    cuo2kaapa2gh.png
  • @ClintStLaurent let's move this to a private convo since it's off-topic for the thread.

  • @DavidOrtinau I'm not completely sure this is the best place for me to report a bug with the Embedding framework.

    But it seems like the StaticResources bug isn't limited to other instances of CreateViewController() on iOS.

    After I call it once, then any other code that references StaticResources throws an exception about not being able to find it.

    I'm using it in Xamarin.Forms to get a native UIViewController for a custom renderer, but after that loads then I can't navigate to any other Pages. (In the TabbedController, all the pages are loaded concurrently, so the issue doesn't actually occur until I navigate to a page that isn't loaded.)

  • Hello.

    Thanks for your work on embedding. It is very helpful for my team.

    I have an error to report. When instantiating an Android Fragment from a Page with a WebView in the xaml, i get this exception.

    Argument Exception: Value cannot be null Parameter name: "startActivityForResult"

    Thanks again

  • @ChrisBoyd this is exactly the place. Can you share your project? Or gist the pertinent pieces so I can have more context.

    I'm not surprised StaticResources are a problem, we need to do work there. A sample of the issue will help.

    I'm not clear on how you're handling navigation, so really need to see that to understand what's going on.

  • @JasonRai engineering has asked for a sample project that demonstrates that issue. File that on Bugzilla please.

  • @DavidOrtinau said:
    @ClintStLaurent let's move this to a private convo since it's off-topic for the thread.

    I'm a bit quick (too quick) to bash - but I try to be equally quick to praise.

    @DavidOrtinau @EZHart @JGoldberger have been working with me for the last week - lots of effort and patience on their part - and there is finally some light at the end of the tunnel with a small project that behaving as expected. There is no way I could have gotten to some of the deep Android code that they did: It's not in my skills. If they hadn't of gotten me over that hump I was about to tell my boss "It can't be done." I've never been so happy to be wrong.

    Thank you all for your help

  • @DavidOrtinau Here's a simplified gist to avoid sharing my entire project.

    https://gist.github.com/cpboyd/4a34d97985c4808a461acead5365554b

    Hopefully it gives a good enough view of what I'm doing:
    I have CustomPageRenderer that generates a UIViewController from PopupSettingsPage.xaml.

    If this occurs, any future attempt to use StaticResources causes an issue.

    This happens if I try to generate a NEW UIViewController from PopupSettingsPage.xaml again (hence my HACK comment in CustomPageRenderer)

    SettingsPage utilizes PRISM's navigation service to navigate to AttachmentsPage.

    If I try to do that AFTER generating the UIViewController, it causes the same issue with StaticResources.

    I can try to create a public sample project from this if needed.

  • @JasonRai @DavidOrtinau The exception with the web view is because the activity you are using does not implement the internal interface IStartActivityForResult (interface that FormsApplicationActivity implements). I got the same problem and after testing the embedded project versus the full forms project the initial loading time saved was not significant enough to continue to port the rest of my forms project to embedded (had some navigation problems and the problem you described that would need a custom renderer to fix).

  • Thanks @AlbertoPuyana

    I am also having navigation problems, but I am looking at another way of fixing them. :)

  • @JasonRai You may also have problems with the DisplayAlert and DisplayActionSheet methods of a Page, if your are using them. The problem is the same, FormsApplicationActivity subscribes to some messages to handle the functionality but you are not using it.

  • @AlbertoPuyana thanks. I don't use them.

    If my navigation alternative works out ill post it here. Looking good so far.

  • Just tried this out on a large Xamarin.iOS based app, and it worked without a hitch!

  • Hello,

    I downloaded your sample Weather to try it. However, when I click on the "your places" button, a unhandled exception occurs. Do you know from where can the problem come from?

    Thank you.

  • @Xavios Need the stack trace from the exception to help you out.

  • @rseostar

    pastebin.com/H5xaZ7h0

    Thank you


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK