Forms9Patch: Simplify multi-device image management in your PCL Xamarin.Forms mobile apps

124

Posts

  • BuildCalcBuildCalc USMember ✭✭✭

    Forms9Patch version 1.1 is now available

    What's so special about it? SVG is now fully supported as a Forms9Patch.Image.Source. This means you can:
    1. apply Tile, AspectFit, AspectFill, and Fill Forms9Patch.Fit to SVG images
    2. apply Rectangle, Square, Circle, Ellipse, and Obround clipping, colored background, and outline (via ElementShape property)
    3. use SVG images as BackgroundImage for Forms9Patch buttons and layouts
    4. use SVG images as IconImage for Forms9Patch buttons

    And, like other Forms9Patch images and fonts, you can store your SVGs as Embedded Resources and then load them as follows:

        var svgImage = new Forms9Patch.Image { Source = "Your_embedded_resource.svg" };
    
        // or more conveniently
        var quickSvgImage = new Forms9Patch.Image("Your_embedded_resource.svg");
    

    And as XAML (if you use a ImageMultiResourceExtension in your Shared/PCL/NetStandard project):

        <Image Source="{local:ImageResource Your_embedded_resource.svg }"/>
    

    The online documentation has still not been updated but the built-in documentation has so you can get guidance via Intellisense. Likewise, the GitHub demo app is great resource for seeing all of the new features in action.

  • renzskarenzska USMember ✭✭

    Ben,

    Thanks again for the great work on this. I just updated to 1.1.0 and am running into an issue.

    The first is that my large text that was autosizing is currently not working with any v1+ version.

    I'm using the following styles:

     <Style x:Key="MainLabelStyle" TargetType="forms9patch:Label">
            <Setter Property="TextColor" Value="{StaticResource PrimaryColor}" />
            <Setter Property="HorizontalTextAlignment" Value="Center" />
            <Setter Property="VerticalTextAlignment" Value="Center" />
            <Setter Property="FontSize" Value="100" />
            <Setter Property="HorizontalOptions" Value="Fill" />
            <Setter Property="Fit" Value="Width" />
        </Style>
    
        <Style x:Key="MainLabelMenuStyle" TargetType="forms9patch:Label" BasedOn="{StaticResource MainLabelStyle}">
            <Setter Property="Margin" Value="20,0,20,0" />
            <Setter Property="FontSize" Value="Large" />
            <Setter Property="FontAttributes" Value="Bold" />
            <Setter Property="HorizontalTextAlignment" Value="Start" />
        </Style>
    

    And using it like so:

    <forms9patch:Label Text="{local:Translate ChangeStatus}"
                Style="{StaticResource MainLabelMenuStyle}" />
    

    When running version 0.10.3.5, it shows as follows (what I'm expecting):

    When running version 1.1.0, it shows as follows:

    This started occurring with 1.0.0.

    Thanks,

    John

  • BuildCalcBuildCalc USMember ✭✭✭

    @renzska -

    Can you send me a quick demo app that replicates this? This is something that the testing didn't catch and I'm not seeing it in the demo app.

  • renzskarenzska USMember ✭✭

    @BuildCalc, I've attached a test project that shows the issue. It is pointing to 0.10.3.5 right now. When I updated both package references to 1.0.0, the font size decreases dramatically as in my previous post.

    Thanks for looking into this.

  • BuildCalcBuildCalc USMember ✭✭✭

    @renzska -

    Thanks, I'll be able to look at it in the morning.

  • BuildCalcBuildCalc USMember ✭✭✭

    @renzska - I've verified the issue (thanks a million for the demo solution). It's also present on the dev branch so I'll start there.

  • BuildCalcBuildCalc USMember ✭✭✭

    @renzska - You found an edge case that I didn't test. I have the dev branch fixed and, after I fix an unrelated bug, I will run through the test suite and then build a new Nuget package.

    In the meantime, I should mention that your demo solution is using the AutoFit=AutoFit.Width property (formerly Fit=Fit.Width) without specifying the number of lines in the Lines property. The default number of lines is zero which should be interpreted by Forms9Patch.Label as a request to ignore the AutoFit property and "scale the font to fit the available space" (limited to a value between FontSize and MinFontSize). I'm not sure that is what you want in the example you provided.

    That being said, the simplest change would be for you to add a Lines=1 to each of your Labels. However, there could be scenarios where some of the lines of text would be longer than others and you would have noticeable differences in font size. If that is important to you, Forms9Patch gives you a couple of options you likely won't find elsewhere.

    The first option is to keep an eye on the FittedFontSize property. In the current versions, it can be done but that approach is obsolete for good reason. When the update to the Nuget package comes out, there will be a public event EventHandler<double> FittedFontSizeChanged; event that passes the latest and greatest FittedFontSize when it is fired. You can then keep track of the smallest FittedFontSize for all of your labels in question and (here's the really cool part) set the SynchronizedFontSize for all of them to that smallest size.

    If that is a bit complicated then, in some cases, the second option might be useful. That's because the SegmentedControl does all of the FittedFontSize and SynchronizedFontSize management automatically. For your use case, you could setup a SegmentedControl with a vertical orientation and no background color or outline. It's not exactly what you've got in the demo app but it could be quite close.

  • renzskarenzska USMember ✭✭

    Thanks for looking into this. I'll update to the new version when it's available and then work at looking at your recommendations.

  • BuildCalcBuildCalc USMember ✭✭✭

    Sounds good. And, if you wish, you can apply the recommendations now and address the issue you're seeing before the next version is available.

  • BuildCalcBuildCalc USMember ✭✭✭

    Forms9Patch 1.1.1 is now available.

    There are a number of bug fixes and improvements so take a look at the release notes.

    Please note that the Forms9Patch nuget package now works for PCL, Shared, and .NetStandard applications. This means the Forms9Patch.NetStandard nuget package is now redundant. With that in mind, Forms9Patch.NetStandard will not be updated beyond 1.1.1. If you are using Forms9Patch.NetStandard, please switch to the Forms9Patch nuget package.

  • gtgatsbygtgatsby JPMember

    I think I found a bug - I don't have a sample project right now, unfortunately, but I'll try to create one if you need.
    Here are the steps I think are causing the problem, though:

    Using a SyncFusion Listview (Guess Xamarin has the same problem, though), the F9P Label control works fine for all the items that are loaded during the initial load. However, if you add items to the ItemsSource after the control has loaded (say during the onScroll event), then for the labels that were added after the initial load, if you click/tap on them, you get a null reference error and crash.

    The stacktrace didn't look too useful -

    at FormsGestures.Droid.NativeGestureListener.get_HandlesLongPresses () [0x00000] in <d6f2bad739c34f839278591ac7602c8c>:0 at FormsGestures.Droid.NativeGestureListener.LongPressTimerStart () [0x00008] in <d6f2bad739c34f839278591ac7602c8c>:0 at FormsGestures.Droid.NativeGestureListener.OnDown (Android.Views.MotionEvent e) [0x0001c] in <d6f2bad739c34f839278591ac7602c8c>:0 at Android.Views.GestureDetector+SimpleOnGestureListener.n_OnDown_Landroid_view_MotionEvent_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_e) [0x0000f] in <848bbd7c681a4975918c72f17d2f5144>:0 at (wrapper dynamic-method) System.Object:3506515b-6998-4c73-affe-dd48d27dac6d (intptr,intptr,intptr)

    I don't need my labels to be tapable, so I just slapped a transparent boxview over them for now, which avoids the problem.

  • gtgatsbygtgatsby JPMember

    I think I found a couple bugs -

    One is reproducible from the sample project. In the LabelAutoFit page, change the text1 string to contain a "
    ". IE:
    static string text1 = "<b><em>Lgoryem</em></b> <br>ipsygum";

    Then run the project and use the settings AutoFit = Width, Lines = 2, Font > 32. The text grows too large and doesn't fit inside the label.

    For the second one, I don't have a sample project right now, unfortunately, but I'll try to create one if you need.
    Here are the steps I think are causing the problem, though:

    Using a SyncFusion Listview (Guess Xamarin has the same problem, though), the F9P Label control works fine for all the items that are loaded during the initial load. However, if you add items to the ItemsSource after the control has loaded (say during the onScroll event), then for the labels that were added after the initial load, if you click/tap on them, you get a null reference error and crash.

    The stacktrace didn't look too useful -

    at FormsGestures.Droid.NativeGestureListener.get_HandlesLongPresses () [0x00000] in <d6f2bad739c34f839278591ac7602c8c>:0 at FormsGestures.Droid.NativeGestureListener.LongPressTimerStart () [0x00008] in <d6f2bad739c34f839278591ac7602c8c>:0 at FormsGestures.Droid.NativeGestureListener.OnDown (Android.Views.MotionEvent e) [0x0001c] in <d6f2bad739c34f839278591ac7602c8c>:0 at Android.Views.GestureDetector+SimpleOnGestureListener.n_OnDown_Landroid_view_MotionEvent_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_e) [0x0000f] in <848bbd7c681a4975918c72f17d2f5144>:0 at (wrapper dynamic-method) System.Object:3506515b-6998-4c73-affe-dd48d27dac6d (intptr,intptr,intptr)

    I don't need my labels to be tapable, so I just slapped a transparent boxview over them for now, which avoids the problem.

  • BuildCalcBuildCalc USMember ✭✭✭
    edited February 2018

    @gtgasby

    Could you slap together a quick demo project that shows these issues? I can't tell you how much faster I can respond when I don't have to try to guess all of the boundary conditions required to replicate the issue.

  • BuildCalcBuildCalc USMember ✭✭✭

    @gtgasby -

    I just ran the demo using your sample text as the value for Forms9Patch.Label.HtmlText property. Yes, the text does get larger (in height) than the constrained box IF the ImposeHeight switch is on. If I turn that switch off, the box grows (in height) to fit the text. The text never got any wider than the box. I tried this on iOS, Android and UWP.

    This may or may not be what you saw. It is the correct behavior for the AutoFit=AutoFit.Width and Lines=2 properties. Perhaps you are looking for Lines=0 or AutoFit.AutoFit.Height?

    Also, please sent me a demo project that demonstrates the null reference error. I'm guessing either the stack trace you shared with me is incomplete or something very strange occurred. I would really like to get to the bottom of it.

  • CarlBartonCarlBarton USInsider, University, Developer Group Leader ✭✭
    edited March 2018

    I just updated to 1.1.1 and been running though any minor adjustments that are required. I have run into one issue that I am not sure how to fix. Here is the Xaml I am using:

    `

            <Grid
                Margin="20">
    
                <Image 
                    Source="{ext:ImageMultiResource GoOutdoors.Core.Resources.SunMoonSwitch.btn_switch_background}" />
    
                <f9p:Image 
                    x:Name="sunMoonSwitch"
                    Source="{ext:ImageMultiResource GoOutdoors.Core.Resources.SunMoonSwitch.btn_switch_sun}"
                    TintColor="{StaticResource PrimaryButtonBackgroundColor}"
                    Fill="AspectFit">
    
                    <f9p:Image.GestureRecognizers>
                        <TapGestureRecognizer Command="{Binding SunMoonSwitchCommand}" />
                    </f9p:Image.GestureRecognizers>
    
                </f9p:Image>
    
            </Grid>
    

    `

    We are swapping images when tapped to make a custom switch.

    On Android all this works fine as before but on iOS the TapGestureRecognizer Command is not getting executed.

    I will send you a sample. I was not able to upload it here. You will also notice that the default behavior with no Fill is not the same as a normal Image.

  • BuildCalcBuildCalc USMember ✭✭✭

    @CarlBarton -

    Yes, please send me some sample code. Without it, I'm not sure if I have a complete picture of what might be causing the issue.

    Also, I wanted to add that, looking at the image you attached, you might also be interested in the following alternative: use a Forms9Patch.Grid containing two Forms9Patch.StateButton elements. Both the grid and the state buttons would have their ElementShape = ElementShape.Obround. The Grid would also have BackgroundColor=Color.White and HasShadow=true. The state buttons would have DefaultState.BackgroundColor= Color.Transparent and their SelectedState.BackgroundColor= Color.Black. Then you could listen for theSelected event on each button and use that to unselect the other.

  • CarlBartonCarlBarton USInsider, University, Developer Group Leader ✭✭

    @BuildCalc

    Thanks for the tip. I will give that a try. It was on my list of things to look at making better "in my spare time" but hadn't got to it yet. :smile:

    Thanks for the quick response -- as always.

    Carl

  • BuildCalcBuildCalc USMember ✭✭✭
    edited March 2018

    @CarlBarton -

    __Short Answer: __

    I'm not sure, but I think you've found a bug with Xamarin.Forms.Platform.iOS.EventTracker!

    __Long Answer: __

    In order to render a Forms9Patch.Image, I have a custom image renderer, Forms9Patch.iOS.ImageRenderer, that uses a custom iOS UIView (Forms9Patch.iOS.SkiaRoundedBoxAndImageView) as a child (it's a very cool class that is mostly code shared across iOS, Android, and UWP). When you do a touch, Xamarin.Forms.Platform.iOS.EventTracker receives a touch notification from Forms9Patch.iOS.SkiaRoundedBoxAndImageView as the touch argument, below.

            bool ShouldReceiveTouch(UIGestureRecognizer recognizer, UITouch touch)
            {
                if (touch.View is IVisualElementRenderer)
                {
                    return true;
                }
    
                // If the touch is coming from the UIView our renderer is wrapping (e.g., if it's  
                // wrapping a UIView which already has a gesture recognizer), then we should let it through
                // (This goes for children of that control as well)
                if (_renderer?.NativeView == null)
                {
                    return false;
                }
    
                if (touch.View.IsDescendantOfView(_renderer.NativeView) && touch.View.GestureRecognizers?.Length > 0)
                {
                    return true;
                }
    
                return false;
            }
    

    Since Forms9Patch.iOS.SkiaRoundedBoxAndImageView isn't a renderer for a Xamarin.Forms.VisualElement (remember, it's a child of one), it fails the touch.View is IVisualElementRenderer test. Since the _render in this case is the renderer for Forms9Patch.iOS.ImageRenderer, it fails the second test (if (_renderer?.NativeView == null)) as well. Next, EventTracker tests to see if touch (a Forms9Patch.iOS.SkiaRoundedBoxAndImageView) is a child of a Xamarin.Forms.VisualElementRenderer - which it is (Forms9Patch.iOS.ImageRenderer). However, instead of testing to see if the _renderer?.NativeView (Forms9Patch.iOS.ImageRenderer) has any gesture recognizers, it tests touch! Perhaps that is intended, but for some reason, the touch event propagation ends there - it isn't being passed up the visual tree. However, if I changed the Xamarin.Forms.Platform.iOS.EventTracker to the following:

            bool ShouldReceiveTouch(UIGestureRecognizer recognizer, UITouch touch)
            {
                if (touch.View is IVisualElementRenderer)
                {
                    return true;
                }
    
                // If the touch is coming from the UIView our renderer is wrapping (e.g., if it's  
                // wrapping a UIView which already has a gesture recognizer), then we should let it through
                // (This goes for children of that control as well)
                if (_renderer?.NativeView == null)
                {
                    return false;
                }
    
                if (touch.View.IsDescendantOfView(_renderer.NativeView) && touch.View.GestureRecognizers?.Length > 0)
                {
                    return true;
                }
    
                if (touch.View.IsDescendantOfView(_renderer.NativeView) && _renderer?.NativeView.GestureRecognizers?.Length > 0)
                {
                    return true;
                }
                return false;
            }
    

    The touch event works.

    Again, I'm not sure if this a Xamarin bug or not but I'm starting to think it's not a Forms9Patch bug (especially since the same code works on Android and UWP).

    I will file a bug report with Xamarin. In the meantime, I would highly recommend either using FormsGestures.Listener as an alternative to Xamarin.Forms.TapGestureRecognizer or switching over to using Forms9Patch.StateButton.

    You can useFormsGestures.Listener in your SandboxPage.Xaml and SandboxPage.Xaml.cs page as follows:

    <ContentPage
        xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        xmlns:f9p="clr-namespace:Forms9Patch;assembly=Forms9Patch"
        xmlns:local="clr-Sandbox"
        x:Class="Sandbox.SandboxPage">
    
        <!--<WebView
            Source="http://georgiawildlife.com/hunting/resources"
            VerticalOptions="FillAndExpand"
            HorizontalOptions="FillAndExpand" />-->
    
        <StackLayout
            VerticalOptions="CenterAndExpand">
    
            <Label
                Text="Standard Image" />
    
            <Image
                Source="icon.png">
    
                <Image.GestureRecognizers>
    
                    <TapGestureRecognizer
                        Command="{Binding TapCommand}" />
    
                </Image.GestureRecognizers>
    
            </Image>
    
            <Label
                Text="Forms9Patch Image" />
    
            <f9p:Image x:Name="myImage"
                Source="{local:ImageMultiResource Sandbox.Resources.icon}">
    
                <!--Image.GestureRecognizers>
    
                    <TapGestureRecognizer
                        Command="{Binding TapCommand}" />
    
                </Image.GestureRecognizers-->
    
            </f9p:Image>
    
        </StackLayout>
    
    </ContentPage>
    
    using Xamarin.Forms;
    
    namespace Sandbox
    {
        public partial class SandboxPage : Xamarin.Forms.ContentPage
        {
            public Command TapCommand { get; set; }
    
            public SandboxPage()
            {
                InitializeComponent();
    
                /*
                TapCommand = new Command(async () =>
                {
                    await DisplayAlert("Tapped", "You tapped it", "OK");
                });
                */
    
                var listener = FormsGestures.Listener.For(myImage);
    
                listener.Tapped += async (object sender, FormsGestures.TapEventArgs e) =>
                {
                    await DisplayAlert("Tapped", "You tapped it", "OK");
                };
    
                BindingContext = this;
            }
        }
    }
    
    
    
  • CarlBartonCarlBarton USInsider, University, Developer Group Leader ✭✭

    @BuildCalc So how the Image control is rendered has changed between 0.10.5 and 1.1.1? It was working in the 0.10.x versions...

  • BuildCalcBuildCalc USMember ✭✭✭

    Yes. My earlier implementation was VERY platform specific, making it quite a pain to maintain. Back when I was implementing UWP, I was done with everything but the button & layout shadows when I discovered just how hard that detail was going to be on UWP. That made me rethink my approach and I took a good hard look at SkiaSharp. In doing so, I (eventually) discovered it would mean > 95% of the renderer code could be shared across platforms. FWIW: this change has also enabled a number of other very cool enhancements, like:
    - shadows on images with transparent backgrounds
    - SVG images
    - background colors for images with transparent backgrounds
    - shaped borders that clip images to the border shape
    - much better image caching

    What does this have to do with the issue you found? As I mentioned, the older versions used my own platform views - that did not implement IVisualElementRenderer. However, the new approach uses SkiaSharp's native views - which does implement IVisualElementRenderer. This fact caused the Xamarin.Forms.Platform.iOS.EventTracker to catch the SkiaSharp native view instead of my renderer - and hence the issue you've seen. This is why I'm guessing this is a Xamarin.Forms bug since the touch event should have been passed up the visual tree but wasn't. One of the reasons I've posted such a lengthy explanation is because I'm hoping the internet will tell me that I'm wrong (and why) so I can fix it!

  • CarlBartonCarlBarton USInsider, University, Developer Group Leader ✭✭

    Thanks. That makes sense.

  • BuildCalcBuildCalc USMember ✭✭✭
    edited May 2018

    Version 1.3.0 means Forms9Patch is now open source!

    No, I'm not orphaning Forms9Patch. In fact, just the opposite. I want more eyeballs on it to find any performance or reliability issues that I haven't noticed. I still have a lot of work catching the docs up to the current state of the code (there are a LOT of undocumented features!) so you'll find more than a few pleasant surprises if you take the time to explore the source.

    https://bitbucket.org/baskren/forms9patch2/src/master/

    Also, the demo app has been updated to show off a few of these new features. Again, you can find it here:

    https://github.com/baskren/Forms9PatchDemo

    This is my first open source project so I am looking forward to learning a lot from the process and your insights.

  • renzskarenzska USMember ✭✭
    edited August 2018

    @BuildCalc I just ran our app on Android 9 and get the following crash on startup:

    08-15 20:31:11.709 31180 31180 I MonoDroid: UNHANDLED EXCEPTION:: com.p3tips.safeut
    08-15 20:31:11.716 31180 31180 I MonoDroid: System.ArgumentException: Version string portion was too short or too long.: com.p3tips.safeut
    08-15 20:31:11.716 31180 31180 I MonoDroid:   at System.Version+VersionResult.SetFailure (System.Version+ParseFailureKind failure, System.String argument) [0x0001c] in <8f6fd9536e634dc1ab5ffbbf15c1e55f>:0 : com.p3tips.safeut
    08-15 20:31:11.716 31180 31180 I MonoDroid:   at System.Version+VersionResult.SetFailure (System.Version+ParseFailureKind failure) [0x00000] in <8f6fd9536e634dc1ab5ffbbf15c1e55f>:0 : com.p3tips.safeut
    08-15 20:31:11.716 31180 31180 I MonoDroid:   at System.Version.TryParseVersion (System.String version, System.Version+VersionResult& result) [0x00029] in <8f6fd9536e634dc1ab5ffbbf15c1e55f>:0 : com.p3tips.safeut
    08-15 20:31:11.716 31180 31180 I MonoDroid:   at System.Version.Parse (System.String input) [0x00023] in <8f6fd9536e634dc1ab5ffbbf15c1e55f>:0 : com.p3tips.safeut
    08-15 20:31:11.716 31180 31180 I MonoDroid:   at System.Version..ctor (System.String version) [0x00014] in <8f6fd9536e634dc1ab5ffbbf15c1e55f>:0 : com.p3tips.safeut
    08-15 20:31:11.716 31180 31180 I MonoDroid:   at Forms9Patch.Droid.OsInfoService.get_Version () [0x00005] in <78a0b497fc3a43108f03cc368361b3b6>:0 : com.p3tips.safeut
    08-15 20:31:11.716 31180 31180 I MonoDroid:   at Forms9Patch.OsInfoService.get_Version () [0x00005] in <8b8b8fecf8a24dc2b4f5c4c5172cacbb>:0 : com.p3tips.safeut
    08-15 20:31:11.716 31180 31180 I MonoDroid:   at Forms9Patch.Droid.SkiaRoundedBoxAndImageView.OnPaintSurface (System.Object sender, SkiaSharp.Views.Android.SKPaintSurfaceEventArgs e) [0x004f1] in <78a0b497fc3a43108f03cc368361b3b6>:0 : com.p3tips.safeut
    08-15 20:31:11.716 31180 31180 I MonoDroid:   at SkiaSharp.Views.Android.SKCanvasView.OnDraw (SkiaSharp.SKSurface surface, SkiaSharp.SKImageInfo info) [0x00013] in <96b23b5b974e4c6a9d6f8d221434e8d3>:0 : com.p3tips.safeut
    08-15 20:31:11.716 31180 31180 I MonoDroid:   at SkiaSharp.Views.Android.SKCanvasView.OnDraw (Android.Graphics.Canvas canvas) [0x000d0] in <96b23b5b974e4c6a9d6f8d221434e8d3>:0 : com.p3tips.safeut
    08-15 20:31:11.716 31180 31180 I MonoDroid:   at Android.Views.View.n_OnDraw_Landroid_graphics_Canvas_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_canvas) [0x0000f] in <e4658a74547d4e3082ceb36ebd5e977c>:0 : com.p3tips.safeut
    08-15 20:31:11.716 31180 31180 I MonoDroid:   at (wrapper dynamic-method) System.Object.0f929bbf-cd0e-4087-b88f-7b0f876c227d(intptr,intptr,intptr): com.p3tips.safeut
    08-15 20:31:11.720 31180 31180 W m.p3tips.safeu: JNI RegisterNativeMethods: attempt to register 0 native methods for android.runtime.JavaProxyThrowable: com.p3tips.safeut
    08-15 20:31:11.722 31180 31180 D AndroidRuntime: Shutting down VM: com.p3tips.safeut
    08-15 20:31:11.726  1161  2901 I am_crash: [31180,0,com.p3tips.safeut,949534276,android.runtime.JavaProxyThrowable,System.ArgumentException: Version string portion was too short or too long.: system_server
    08-15 20:31:11.726  1161  2901 I am_crash:   at System.Version+VersionResult.SetFailure (System.Version+ParseFailureKind failure, System.String argument) [0x0001c] in <8f6fd9536e634dc1ab5ffbbf15c1e55f>:0 : system_server
    08-15 20:31:11.726  1161  2901 I am_crash:   at System.Version+VersionResult.SetFailure (System.Version+ParseFailureKind failure) [0x00000] in <8f6fd9536e634dc1ab5ffbbf15c1e55f>:0 : system_server
    08-15 20:31:11.726  1161  2901 I am_crash:   at System.Version.TryParseVersion (System.String version, System.Version+VersionResult& result) [0x00029] in <8f6fd9536e634dc1ab5ffbbf15c1e55f>:0 : system_server
    08-15 20:31:11.726  1161  2901 I am_crash:   at System.Version.Parse (System.String input) [0x00023] in <8f6fd9536e634dc1ab5ffbbf15c1e55f>:0 : system_server
    08-15 20:31:11.726  1161  2901 I am_crash:   at System.Version..ctor (System.String version) [0x00014] in <8f6fd9536e634dc1ab5ffbbf15c1e55f>:0 : system_server
    08-15 20:31:11.726  1161  2901 I am_crash:   at Forms9Patch.Droid.OsInfoService.get_Version () [0x00005] in <78a0b497fc3a43108f03cc368361b3b6>:0 : system_server
    08-15 20:31:11.726  1161  2901 I am_crash:   at Forms9Patch.OsInfoService.get_Version () [0x00005] in <8b8b8fecf8a24dc2b4f5c4c5172cacbb>:0 : system_server
    08-15 20:31:11.726  1161  2901 I am_crash:   at Forms9Patch.Droid.Sk^: system_server
    08-15 20:31:11.727  1161  2901 W ActivityManager:   Force finishing activity com.p3tips.safeut/md52c34627382ae872580fa97c393738482.MainActivity: system_server
    08-15 20:31:11.727  1161  2901 I am_finish_activity: [0,97930172,3045,com.p3tips.safeut/md52c34627382ae872580fa97c393738482.MainActivity,force-crash]: system_server
    08-15 20:31:11.727  1161  2901 I am_focused_stack: [0,0,75,finishActivity adjustFocus]: system_server
    08-15 20:31:11.727  1161  2901 I wm_task_moved: [2,0,2147483647]: system_server
    08-15 20:31:11.728  1161  2901 I am_pause_activity: [0,97930172,com.p3tips.safeut/md52c34627382ae872580fa97c393738482.MainActivity,userLeaving=false]: system_server
    08-15 20:31:11.729  1161  2901 I sysui_action: [316,-1]: system_server
    08-15 20:31:11.729  1161  1185 I sysui_count: [window_time_0,69]: system_server
    08-15 20:31:11.729  1161  2901 I sysui_multi_action: [757,316,758,4,759,-1]: system_server
    08-15 20:31:11.729  1161  1185 I sysui_multi_action: [757,803,799,window_time_0,802,69]: system_server
    08-15 20:31:11.729 31180 31180 I Process : Sending signal. PID: 31180 SIG: 9: com.p3tips.safeut
    08-15 20:31:11.734   790   790 E lowmemorykiller: Error writing /proc/31180/oom_score_adj; errno=22: /system/bin/lmkd
    08-15 20:31:11.747  1161  1445 W InputDispatcher: channel '7ce269 com.p3tips.safeut/md52c34627382ae872580fa97c393738482.MainActivity (server)' ~ Consumer closed input channel or an error occurred.  events=0x9: system_server
    08-15 20:31:11.747  1161  1445 E InputDispatcher: channel '7ce269 com.p3tips.safeut/md52c34627382ae872580fa97c393738482.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!: system_server
    08-15 20:31:11.748   719   719 I Zygote  : Process 31180 exited due to signal (9)
    08-15 20:31:11.748  1161  2180 I ActivityManager: Process com.p3tips.safeut (pid 31180) has died: vis  +99TOP : system_server
    08-15 20:31:11.748  1161  2180 I am_proc_died: [0,31180,com.p3tips.safeut,199,2]: system_server
    08-15 20:31:11.748  1161  1188 W libprocessgroup: kill(-31180, 9) failed: No such process: system_server
    08-15 20:31:11.748  1161  2152 I WindowManager: WIN DEATH: Window{7ce269 u0 com.p3tips.safeut/md52c34627382ae872580fa97c393738482.MainActivity}: system_server
    08-15 20:31:11.748  1161  2152 W InputDispatcher: Attempted to unregister already unregistered input channel '7ce269 com.p3tips.safeut/md52c34627382ae872580fa97c393738482.MainActivity (server)': system_server
    08-15 20:31:11.748  1161  1188 I libprocessgroup: Successfully killed process cgroup uid 10204 pid 31180 in 0ms: system_server
    08-15 20:31:11.748  1161  2180 I am_uid_stopped: 10204: system_server
    08-15 20:31:11.758  1161  2180 I wm_task_removed: [3045,removeAppToken: last token]: system_server
    08-15 20:31:11.758  1161  2180 I am_remove_task: [3045,75]: system_server
    08-15 20:31:11.758  1161  2180 I wm_task_removed: [3045,removeTask]: system_server
    

    Here is the info I'm using:

    Version Number: 345
    Version Name: 3.0.11

    Any ideas?

  • BuildCalcBuildCalc USMember ✭✭✭

    @renzska -

    When you say Android 9, do you mean API level 28?

    • Ben
  • BuildCalcBuildCalc USMember ✭✭✭

    @renzska - OK, I think I see what's going on (assuming that, yes, you're using API 28). I've implemented a fix and will be releasing an update either today or Monday (depending on how the tests go).

  • renzskarenzska USMember ✭✭
    Yes, API 28. Thanks for the quick turnaround on this!

    - John
  • renzskarenzska USMember ✭✭

    @BuildCalc, any luck with the update? Schools are back in session and we're trying to get an update out as we're starting to get more crash reports. I could pull down the latest and build it on my end for testing and usage until you have a new version available. Which branch would be the best to do that from?

    Thanks again,

    John

  • BuildCalcBuildCalc USMember ✭✭✭

    Still working on fixing a UWP issue with the next release - but it should be good for your needs (all iOS and Android test pass). It's the "release-crash" branch.

  • renzskarenzska USMember ✭✭

    @BuildCalc, I've been unsuccessful in getting Forms9Patch to build so far. Right now I'm getting an issue with the Forms.Flex not being present. I pulled the submodules and linked the packages folders (on Mac), but haven't had time to work past that. Any ETA on an updated release with the UWP issue and the Android 9 (API 28) issue resolved?

    Thanks,

    John

  • Thanks for the good ideas to bring it. I know a lot more.www.ufa007.com/ :) : J

  • BuildCalcBuildCalc USMember ✭✭✭
    edited September 2018

    @renzska

    Thank you for your patience with me on this. I really wanted to get the updates right before submitting a new NuGet release. I've just uploaded 1.4.0 to NuGet.org and it should be available in a few minutes.

  • BuildCalcBuildCalc USMember ✭✭✭

    Forms9Patch 1.5 is available

    This is a maintenance update as there is no new functionality. However, under the covers, there are two important changes for reliability and performance:

    • Image and shape rendering has been refactored to eliminate platform specific code in favor of SkiaSharp.Views.Forms. This has eliminated a number of platform specific bugs!
    • Popups have also been refactored to eliminate the need for Forms9Patch.RootPage by using Rg.Plugins.Popups. This has resulted in fixing issues with using popups in pages that have been presented modally as well as popups presented over the Master page in MasterDetailPage.
  • FavasFavas INMember ✭✭

    @BuildCalc How can I set a native resource into forms9Patch Image control.?
    <forms9Patch:Image Source="ic_send.png"></forms9Patch:Image>
    Above one does not work.

  • BuildCalcBuildCalc USMember ✭✭✭

    @Favas - With Forms9Patch, I made a difference design decision with the default behavior of ImageSource. Rather than it referencing a file handle, by default it references a embedded resource in the main application assembly. Thus, in your example (if I remember correctly), it should be looking for an embedded resource named "ic_send.png" in the main application assembly (the assembly for your cross platform project).

    Why? Because my intent was to support a more cross platform approach in an effort to reduce the number of places needed to maintain resource files.

  • FavasFavas INMember ✭✭

    @BuildCalc I want to check the performance difference between Embedded(on Shared project) and Native resources(on platform specific projects). I tried "ic_send.png" as Embedded resource it works, but not from native resources.

  • BuildCalcBuildCalc USMember ✭✭✭

    @Favas -

    I would recommend testing it using code, rather than XAML. Forms9Patch.ImageSource.FromMultiResource or Forms9Patch.ImageSource.FromResource for your embedded resources and Xamarin.Forms.ImageSource.FromFile for your files. You also might want to compare their performance with both Xamarin.Forms.Image and Forms9Patch.Image as Forms9Patch.Image has built-in image caching for Embedded Resources and Files.

  • IcolinoIcolino Member ✭✭
    edited March 4

    Hi @Favas . First of all thanks for the open source package. I am kinda new to Xamarin I have been using it for 2 months. So I have an application that requires Google Authentication which is fine and working properly. But my button is just a normal button and I am trying to use Google guidelines to create their button. I downloaded Google drawables from this page

    Since I made a new account I can't post links, so delete the ? inside htt?ps if you wish to use them :

    htt?ps://developers.google.com/identity/branding-guidelines

    htt?ps://developers.google.com/identity/images/signin-assets.zip.

    But no matter how I set up the button. I don't get the desired result.

    The closest I was to getting it to look properly was this :

        <f9p:Button  Text = "Sign in with xxhdpi"
                         TextColor="White"
                         FontSize="14"
                         FontFamily="sans-serif-medium"
                         WidthRequest="60"
                         >
                <f9p:Button.BackgroundImage>
                    <f9p:Image Source="{local:ImageMultiResource TestingApp.Resources.Images.btn_google_signin_dark_normal_xxhdpi}"/>
                </f9p:Button.BackgroundImage>
    
    
            </f9p:Button>
    

    I tried using a grid with image and button . Didn't work out. Tried using your statebutton, but google offers the icon for signin with the blue area for stretching. So the Icon is weird. If i use it for background only, I get the same problem as with normal button.

    First image is of the statebutton. The other three are from my experiments with button with different drawables.
    I would be eternaly gratefull if someone would enlighten me as to what to do.

    Same reason as for the links up, delete the ? inside htt?ps if you wish to see the images :
    h?ttps://imgur.com/a/gG87eWA

  • BuildCalcBuildCalc USMember ✭✭✭

    @Icolino

    I've actually done this before. Here is a general outline of what I did:

    1. Put your multi-platform icon files into your .NetStandard project as Embedded Resources. This means that I found all of the various resolutions provided by Google (_xxhdpi, _xhdpi, _hdpi, _mdpi, etc) and then renamed them to the followiing:

      And then put them in to the "Resources/Google" folder in my project ("FormsFirebase.Ui"). So, for example, the EmbeddedResourceId for the first file, in the above list, is "[email protected]¾x.png".

      As you will see in a moment, renaming these files, as shown above, will allow Forms9Patch.Button to pick the right image for the right screen resolution (so it will look great) - freeing you from having to manage this.

    2. In your Forms9Patch.Button, refer to the above icon image in a resolution independent fashion. This can be done a couple of ways. One of the more verbose ways is:

        myButton.IconImage = new Forms9Patch.Image
        {
            Source = Forms9Patch.ImageSource.FromMultiResource("FormsFirebase.Ui.Resources.Google.icon", GetType().Assembly),
            Padding = new Thickness(1, 1, 5, 1),
            TintIcon = false,
        };
    
    

    Notice that I am able to set the padding of the IconImage. This is in addition to being able to set the Forms9Patch.Button.Padding and the Forms9Patch.Button.Spacing (the distance between the IconImage and the Text or HtmlText, depending on if HasTightSpacing has been set to true).

    Now for a bit of proselytization (please forgive me if this does not apply to you): I see that you used XAML for your sample code. Notice I didn't in my response. If you are new to .Net and/or Xamarin.Forms, I would highly recommend not using XAML. Don't get me wrong, XAML is great - it's just not for beginners. Why? There's just too many things going on under the covers that, as a beginner, will trip you up and slow you down. Rather, I would recommend you write all of your UI in C# so you can learn to manage your properties and learn how binding really works. Once you have mastered making very efficient layouts with the best "context appropriate" use of binding, then you're ready for XAML. For me, the real test was being able to make very a complex cell layout in a large list in a ListView smoothly scroll on a low-end Android phone. After that experience, I was able to take advantage of all the benefits of developing in XAML (and there are many) without worrying about being shackled by my novice mistakes.

  • IcolinoIcolino Member ✭✭
    edited March 7

    Awesome explanation I loved it and now my xaml buttons are working as they should. So I am absolutely grateful for that.

    But I would love to be converted to your religion so I am trying to make it work with c#. To no avail.
    First Padding and Tint property are not there.

    And more importantly Icon is not being shown. But the size and height is appropriate. I tried with different Icons so it does somehow figure out the size correctly but leaves it empty. Resources are embeded and at appropriate place, they work through xaml.

    It's probably something simple. My project is Xamarin.Forms perhaps it's due to that somehow.

    namespace TestingApp
    {
        class Test : ContentPage
        {
            public Test()
            {
                var button = new Forms9Patch.Button { Text = "Google Sign In" };
    
                button.IconImage = new Forms9Patch.Image
                {
                    Source = Forms9Patch.ImageSource.FromMultiResource("TestingApp.Resources.Images.GoogleIcon.btn_google_dark_normal", GetType().Assembly),
                    TintColor = Color.Beige
                };
    
                Content = new StackLayout
                {
                    Children =
                    {
                    button
                    }
                };
            }
        }
    }
    

    The end result of above code (question mark again) :

    htt?ps://imgur.com/yXbFaF0

    Thank you once more.

  • BuildCalcBuildCalc USMember ✭✭✭

    If your XAML is working then getting your C# to work should be a slam dunk. I have a couple requests:

    1. Show me a listing of the contents of your "TestingApp/Resources/Images/" directory.
    2. Replace the "TintColor=Color.Beige" line with "TintIcon=false"
Sign In or Register to comment.