Search code examples
xamarin.formsxamarin.communitytoolkit

Xamarin Forms: Facing weird issues after installing the Xamarin.CommunityToolkit


Recently I have installed Xamarin.CommunityToolkit (Version: 1.3.1) for implementing the BadgeView. Also updated the Xamarin.Forms (Version: 5.0.0.2291) to the latest version. After that, I am facing some weird issues on my project. After the login the app is not opening the home page, scroll view is not working, collectionview scroll is not working, even some icon taps are also not firing.

All these features are working fine before installing Xamarin.CommunityToolkit. I have only installed CommunityToolkit and XF latest version. Are there any other packages or initialization required for the proper working of CommunityToolkit?

Other Nuget Packages in the Project

<PackageReference Include="Acr.UserDialogs" Version="7.1.0.446" />
<PackageReference Include="DLToolkit.Forms.Controls.FlowListView" Version="2.0.11" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.16" />
<PackageReference Include="Microsoft.Bcl" Version="1.1.10" />
<PackageReference Include="Microsoft.Bcl.Build" Version="1.0.21" />
<PackageReference Include="Microsoft.Net.Http" Version="2.2.29" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="PCLStorage" Version="1.0.2" />
<PackageReference Include="Plugin.MediaManager" Version="1.0.9" />
<PackageReference Include="Plugin.MediaManager.Forms" Version="0.8.11" />
<PackageReference Include="Rg.Plugins.Popup" Version="1.1.5.180" />
<PackageReference Include="SkiaSharp" Version="1.68.1-rc.147" />
<PackageReference Include="sqlite-net-pcl" Version="1.6.292" />
<PackageReference Include="Syncfusion.Xamarin.SfListView" Version="17.3.0.30" />
<PackageReference Include="Xam.Plugin.Connectivity" Version="3.2.0" />
<PackageReference Include="Xam.Plugin.HtmlLabel" Version="2.1.0" />
<PackageReference Include="Xam.Plugin.LatestVersion" Version="1.1.2" />
<PackageReference Include="Xam.Plugin.Media" Version="4.0.1.5" />
<PackageReference Include="Xam.Plugin.SimpleAudioPlayer" Version="1.3.1" />
<PackageReference Include="Xam.Plugins.Forms.ImageCircle" Version="3.0.0.5" />
<PackageReference Include="Xamarin.Essentials" Version="1.5.3.2" />
<PackageReference Include="Xamarin.FFImageLoading" Version="2.4.11.982" />
<PackageReference Include="Xamarin.FFImageLoading.Forms" Version="2.4.11.982" />
<PackageReference Include="Xamarin.FFImageLoading.Svg" Version="2.4.11.982" />
<PackageReference Include="Xamarin.FFImageLoading.Svg.Forms" Version="2.4.11.982" />
<PackageReference Include="Xamarin.FFImageLoading.Transformations" Version="2.4.11.982" />
<PackageReference Include="Xamarin.Forms" Version="4.8.0.1269" />
<PackageReference Include="XamForms.Enhanced.Calendar" Version="1.2.2" />
<PackageReference Include="Xamarin.Plugin.FilePicker" Version="2.1.34" />

Which package has compatibility issue with Xamarin.CommunityToolkit?

Update

I found that the issue is happening when I set the text value for badgeview from xaml.cs file after an API call. When I comment that part there is no issue. My issues are entire page scrollview is not working, collectionview is not working, text on badgeview is not working also app is very slow. Sample project: https://drive.google.com/file/d/1B2bGcCxqJWmoU5tLLbNwUaW04mjAJm4S/view?usp=sharing There is a function GetUserMedals() in HomePage1, I am setting badgeview text on that function. For reproducing this issue I need to add some private APIs into the demo. Please don't post it anywhere.


Solution

  • Got a perfect solution from my Microsoft thread.

    Write a new badgeview.

    Firstly, create CircleView.cs

    using System;
    using System.Collections.Generic;
    using System.Text;
    using Xamarin.Forms;
    namespace MyProject
    {
        public partial class CircleView : BoxView
        {
            public static readonly BindableProperty CornerRadiusProperty = BindableProperty.Create(nameof(CornerRadius), typeof(double), typeof(CircleView), 0.0);
            public double CornerRadius
            {
                get { return (double)GetValue(CornerRadiusProperty); }
                set { SetValue(CornerRadiusProperty, value); }
            }
            public CircleView()
            {
               // InitializeComponent();
            }
        }
    }
    

    Then create contentview called BadgeView.xaml and edit it to the Grid.

    <?xml version="1.0" encoding="UTF-8"?>
    <Grid      xmlns="http://xamarin.com/schemas/2014/forms"     
               xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local1="clr-namespace:MyProject"
               x:Class="MyProject.BadgeView"     
               HeightRequest="30"     
               WidthRequest="30">
        <local1:CircleView x:Name="BadgeCircle" HeightRequest="30" WidthRequest="30" CornerRadius="30" VerticalOptions="Center" HorizontalOptions="Center" />
        <Label x:Name="BadgeLabel" TextColor="White" VerticalOptions="Center" HorizontalOptions="Center" VerticalTextAlignment="Center" HorizontalTextAlignment="Center" FontSize="15"/>
    </Grid>
    

    Here is BadgeView.xaml.cs.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Xamarin.Forms;
    using Xamarin.Forms.Xaml;
    namespace MyProject
    {
        [XamlCompilation(XamlCompilationOptions.Compile)]
        public partial class BadgeView : Grid
        {
            public static BindableProperty TextProperty = BindableProperty.Create("Text", typeof(string), typeof(BadgeView), "0", propertyChanged: (bindable, oldVal, newVal) =>
            {
                var view = (BadgeView)bindable;
                view.BadgeLabel.Text = (string)newVal;
            });
            public static BindableProperty BadgeColorProperty = BindableProperty.Create("BadgeColor", typeof(Color), typeof(BadgeView), Color.Blue, propertyChanged: (bindable, oldVal, newVal) =>
            {
                var view = (BadgeView)bindable;
                view.BadgeCircle.BackgroundColor = (Color)newVal;
            });
            public string Text
            {
                get
                {
                    return (string)GetValue(TextProperty);
                }
                set
                {
                    SetValue(TextProperty, value);
                }
            }
            public Color BadgeColor
            {
                get
                {
                    return (Color)GetValue(BadgeColorProperty);
                }
                set
                {
                    SetValue(BadgeColorProperty, value);
                }
            }
            public BadgeView()
            {
                InitializeComponent();
                BadgeLabel.Text = Text;
                BadgeCircle.BackgroundColor = BadgeColor;
            }
        }
    }
    

    Then you need to create a custom renderer for this CircleView in android.

    using Android.App;
    using Android.Content;
    using Android.Graphics;
    using Android.OS;
    using Android.Runtime;
    using Android.Util;
    using Android.Views;
    using Android.Widget;
    using MyProject;
    using MyProject.Droid;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Xamarin.Forms;
    using Xamarin.Forms.Platform.Android;
    [assembly: ExportRenderer(typeof(CircleView), typeof(CircleViewRenderer))]
    namespace MyProject.Droid
    {
        public class CircleViewRenderer : BoxRenderer
        {
            private float _cornerRadius;
            private RectF _bounds;
            private Path _path;
            public CircleViewRenderer(Context context) : base(context)
            {
            }
            protected override void OnElementChanged(ElementChangedEventArgs<BoxView> e)
            {
                base.OnElementChanged(e);
                if (Element == null)
                {
                    return;
                }
                var element = (CircleView)Element;
                _cornerRadius = TypedValue.ApplyDimension(ComplexUnitType.Dip, (float)element.CornerRadius, Context.Resources.DisplayMetrics);
            }
            protected override void OnSizeChanged(int w, int h, int oldw, int oldh)
            {
                base.OnSizeChanged(w, h, oldw, oldh);
                if (w != oldw && h != oldh)
                {
                    _bounds = new RectF(0, 0, w, h);
                }
                _path = new Path();
                _path.Reset();
                _path.AddRoundRect(_bounds, _cornerRadius, _cornerRadius, Path.Direction.Cw);
                _path.Close();
            }
            public override void Draw(Canvas canvas)
            {
                canvas.Save();
                canvas.ClipPath(_path);
                base.Draw(canvas);
                canvas.Restore();
            }
        }
    }
    

    For iOS renderer.

    [assembly: ExportRenderer(typeof(CircleView), typeof(CircleViewRenderer))]
    namespace MyProject.iOS
    {
        public class CircleViewRenderer : BoxRenderer
        {
            protected override void OnElementChanged(ElementChangedEventArgs<BoxView> e)
            {
                base.OnElementChanged(e);
     
                if (Element == null)
                    return;
     
                Layer.MasksToBounds = true;
                Layer.CornerRadius = (float)((CircleView)Element).CornerRadius / 2.0f;
            }
     
        }
    }
    

    In the end, we can use it in your HomePage1.cs Find the tag copy following code

    <Grid Grid.Row="0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="33*" />
            <ColumnDefinition Width="34*" />
            <ColumnDefinition Width="33*" />
        </Grid.ColumnDefinitions>
            <StackLayout   Grid.Column="0">
                <Grid>
                    <Grid TranslationY="-15">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="*" />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                        <Image 
                            Grid.Row="0" 
                            Source="ic_white_dot_xx.png">
                            <Image.HeightRequest>
                                    <OnIdiom x:TypeArguments="x:Double">
                                        <OnIdiom.Phone>120</OnIdiom.Phone>
                                        <OnIdiom.Tablet>240</OnIdiom.Tablet>
                                        <OnIdiom.Desktop>120</OnIdiom.Desktop>
                                    </OnIdiom>
                                </Image.HeightRequest>
                                <Image.WidthRequest>
                                    <OnIdiom x:TypeArguments="x:Double">
                                        <OnIdiom.Phone>120</OnIdiom.Phone>
                                        <OnIdiom.Tablet>240</OnIdiom.Tablet>
                                        <OnIdiom.Desktop>120</OnIdiom.Desktop>
                                    </OnIdiom>
                                </Image.WidthRequest>
                            </Image>
                        <Image 
                            HorizontalOptions="CenterAndExpand" 
                            VerticalOptions="CenterAndExpand"
                            Source="ic_medal_xx.png" >
                            <Image.WidthRequest>
                                    <OnIdiom x:TypeArguments="x:Double">
                                        <OnIdiom.Phone>60</OnIdiom.Phone>
                                        <OnIdiom.Tablet>90</OnIdiom.Tablet>
                                        <OnIdiom.Desktop>60</OnIdiom.Desktop>
                                    </OnIdiom>
                                </Image.WidthRequest>
                                <Image.HeightRequest>
                                    <OnIdiom x:TypeArguments="x:Double">
                                        <OnIdiom.Phone>60</OnIdiom.Phone>
                                        <OnIdiom.Tablet>90</OnIdiom.Tablet>
                                        <OnIdiom.Desktop>60</OnIdiom.Desktop>
                                    </OnIdiom>
                                </Image.HeightRequest>
                            </Image>
                        </Grid>
                 <views:BadgeView    x:Name="medals_badge" Text="30" BadgeColor="Red" VerticalOptions="Start" HorizontalOptions="End"/>
                </Grid>
            </StackLayout>
            <StackLayout Grid.Column="1">
                <Grid>
                    <Grid   TranslationY="-15">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*" />
                            <RowDefinition Height="Auto" />
                        </Grid.RowDefinitions>
                        <Image 
                        Grid.Row="0" 
                        Source="ic_white_dot_xx.png">
                            <Image.HeightRequest>
                                <OnIdiom x:TypeArguments="x:Double">
                                    <OnIdiom.Phone>120</OnIdiom.Phone>
                                    <OnIdiom.Tablet>240</OnIdiom.Tablet>
                                    <OnIdiom.Desktop>120</OnIdiom.Desktop>
                                </OnIdiom>
                            </Image.HeightRequest>
                            <Image.WidthRequest>
                                <OnIdiom x:TypeArguments="x:Double">
                                    <OnIdiom.Phone>120</OnIdiom.Phone>
                                    <OnIdiom.Tablet>240</OnIdiom.Tablet>
                                    <OnIdiom.Desktop>120</OnIdiom.Desktop>
                                </OnIdiom>
                            </Image.WidthRequest>
                        </Image>
                        <Image 
                        HorizontalOptions="CenterAndExpand" 
                        VerticalOptions="CenterAndExpand"
                        Source="ic_badge_xx.png" >
                            <Image.WidthRequest>
                                <OnIdiom x:TypeArguments="x:Double">
                                    <OnIdiom.Phone>60</OnIdiom.Phone>
                                    <OnIdiom.Tablet>90</OnIdiom.Tablet>
                                    <OnIdiom.Desktop>60</OnIdiom.Desktop>
                                </OnIdiom>
                            </Image.WidthRequest>
                            <Image.HeightRequest>
                                <OnIdiom x:TypeArguments="x:Double">
                                    <OnIdiom.Phone>60</OnIdiom.Phone>
                                    <OnIdiom.Tablet>90</OnIdiom.Tablet>
                                    <OnIdiom.Desktop>60</OnIdiom.Desktop>
                                </OnIdiom>
                            </Image.HeightRequest>
                        </Image>
                    </Grid>
                    <views:BadgeView    x:Name="badges_badge"   Text="30" BadgeColor="Red" VerticalOptions="Start" HorizontalOptions="End"/>
                </Grid>
            </StackLayout>
            <StackLayout Grid.Column="2">
         <Grid>
            <Grid  TranslationY="-15">
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Image 
                    Grid.Row="0" 
                    Source="ic_white_dot_xx.png">
                    <Image.HeightRequest>
                        <OnIdiom x:TypeArguments="x:Double">
                            <OnIdiom.Phone>120</OnIdiom.Phone>
                            <OnIdiom.Tablet>240</OnIdiom.Tablet>
                            <OnIdiom.Desktop>120</OnIdiom.Desktop>
                        </OnIdiom>
                    </Image.HeightRequest>
                    <Image.WidthRequest>
                        <OnIdiom x:TypeArguments="x:Double">
                            <OnIdiom.Phone>120</OnIdiom.Phone>
                            <OnIdiom.Tablet>240</OnIdiom.Tablet>
                            <OnIdiom.Desktop>120</OnIdiom.Desktop>
                        </OnIdiom>
                    </Image.WidthRequest>
                </Image>
                <Image 
                  HorizontalOptions="Center"
                    VerticalOptions="Center"
                    Source="ic_star_xx.png" >
                    <Image.WidthRequest>
                        <OnIdiom x:TypeArguments="x:Double">
                            <OnIdiom.Phone>60</OnIdiom.Phone>
                            <OnIdiom.Tablet>90</OnIdiom.Tablet>
                            <OnIdiom.Desktop>60</OnIdiom.Desktop>
                        </OnIdiom>
                    </Image.WidthRequest>
                    <Image.HeightRequest>
                        <OnIdiom x:TypeArguments="x:Double">
                            <OnIdiom.Phone>60</OnIdiom.Phone>
                            <OnIdiom.Tablet>90</OnIdiom.Tablet>
                            <OnIdiom.Desktop>60</OnIdiom.Desktop>
                        </OnIdiom>
                    </Image.HeightRequest>
                </Image>
               </Grid>
            <views:BadgeView   x:Name="star_badge"   Text="30" BadgeColor="Red" VerticalOptions="Start" HorizontalOptions="End"/>
           </Grid>
         </StackLayout>
    </Grid>
    

    In the end, open your layout background code, you can find the GetUserMedals method. Set it directly.

    medals_badge.Text = urlDetails.medals;
    badges_badge.Text = urlDetails.badges;
    star_badge.Text = urlDetails.stars;