Xamarin Forms:安装 Xamarin.CommunityToolkit 后遇到奇怪的问题

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

最近我安装了 Xamarin.CommunityToolkit (Version: 1.3.1) 来实现 BadgeView。还将 Xamarin.Forms (Version: 5.0.0.2291) 更新到最新版本。在那之后,我的项目遇到了一些奇怪的问题。登录后应用程序打不开主页,滚动视图不工作,collectionview 滚动不工作,甚至一些图标点击也没有触发。

在安装 Xamarin.CommunityToolkit 之前,所有这些功能都运行良好。我只安装了 CommunityToolkitXF 最新版本。 CommunityToolkit 的正常工作是否需要任何其他包或初始化?

项目中的其他 Nuget 包

<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" />

哪个软件包与 Xamarin.CommunityToolkit 存在兼容性问题?

更新

我发现当我在 API 调用后从 xaml.cs 文件中设置 badgeview 的文本值时出现了问题。当我评论那部分时,没有问题。我的问题是整个页面滚动视图不工作,collectionview 不工作,badgeview 上的文本不工作,应用程序也很慢。 示例项目:https://drive.google.com/file/d/1B2bGcCxqJWmoU5tLLbNwUaW04mjAJm4S/view?usp=sharing HomePage1 中有一个函数 GetUserMedals(),我正在为该函数设置 badgeview 文本。为了重现这个问题,我需要在演示中添加一些私有 APIs。请不要post它在任何地方。

从我的Microsoft thread那里得到了一个完美的解决方案。

写一个新的徽章视图。

首先,创建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();
        }
    }
}

然后创建名为 BadgeView.xaml 的内容视图并将其编辑到网格。

<?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>

这里是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;
        }
    }
}

然后您需要在 android 中为此 CircleView 创建一个自定义渲染器。

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();
        }
    }
}

对于 iOS 渲染器。

[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;
        }
 
    }
}

最后,我们可以在你的HomePage1.cs中找到标签复制下面的代码

<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>

最后打开你的layout后台代码,可以找到GetUserMedals方法。直接设置。

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