c# - 为什么滚动这个 xamarin 页面这么慢?

标签 c# performance xamarin xamarin.forms xamarin.android

我正在开发一个 xamarin 项目(android,尚未在 ios 中测试),并且注意到我的 UI 在滚动(scrollview/observablecollection)时很慢。我在 Xamarin official page 阅读了一些有关性能的建议并尝试过,也做了其他测试,但没有收获。

感觉就像当用户尝试滚动某些内容时,它正在快速重复卡住/释放用户界面。

这是我出于测试目的尝试但没有成功的方法:

  • 删除了 map
  • 将图像更改为 ffimageloading 缓存图像
  • 已删除标签
  • 删除了不必要的 StackLayout
  • 从 ScrollView 标记中删除了 InputTransparent="True"

我的xaml:

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:ContentView="clr-namespace:MasterDetailPageNavigation.XAML"
             x:Class="MasterDetailPageNavigation.VisualizarProfissional"
             xmlns:views="clr-namespace:MasterDetailPageNavigation.XAML"
             xmlns:maps="clr-namespace:Xamarin.Forms.Maps;assembly=Xamarin.Forms.Maps"
             xmlns:controls="clr-namespace:CustomControls.Controls"
             Title="My app" BackgroundColor="#58C8A2">
  <ContentPage.Resources>
    <Style x:Key="Especs" TargetType="Label">
        <Setter Property="Margin" Value="0" />
        <Setter Property="FontSize" Value="12" />
        <Setter Property="BackgroundColor" Value="#f0f0f0" />
        <Setter Property="Padding" Value="2" />
    </Style>
    <StyleSheet Source="VisualizarProfissional.css" />
  </ContentPage.Resources>
  <ContentPage.Content>
      <Grid>
          <Grid.RowDefinitions>
              <RowDefinition Height="50" />
              <RowDefinition Height="*" />
          </Grid.RowDefinitions>

          <ContentView:TopBarBack Grid.Row="0" Grid.Column="0" Margin="0">
            <x:Arguments>
                <x:String>Voltar para a lista</x:String>
            </x:Arguments>
         </ContentView:TopBarBack>

         <ScrollView InputTransparent="True" x:Name="ScrollProfissional" Grid.Row="1" Grid.Column="0" HorizontalOptions="FillAndExpand" VerticalScrollBarVisibility="Always" BackgroundColor="White">

             <Grid VerticalOptions="StartAndExpand" HorizontalOptions="Fill">

                 <Grid.ColumnDefinitions>
                     <ColumnDefinition Width="*"></ColumnDefinition>
                 </Grid.ColumnDefinitions>
                 <Grid.RowDefinitions>
                     <RowDefinition Height="40"></RowDefinition>
                     <RowDefinition Height="auto"></RowDefinition>
                     <RowDefinition Height="auto"></RowDefinition>
                     <RowDefinition Height="150"></RowDefinition>
                     <RowDefinition Height="40"></RowDefinition>
                     <RowDefinition Height="auto"></RowDefinition>
                     <RowDefinition Height="50"></RowDefinition>
                     <RowDefinition Height="220" x:Name="RowMap"></RowDefinition>
                     <RowDefinition Height="auto"></RowDefinition>
                     <RowDefinition Height="auto"></RowDefinition>
                     <RowDefinition Height="auto"></RowDefinition>
                     <RowDefinition Height="auto"></RowDefinition>
                 </Grid.RowDefinitions>


                 <Label x:Name="xCategoria" TextColor="#8e8e8e" FontSize="14" Grid.Column="0" Grid.Row="0" VerticalOptions="End" HorizontalOptions="StartAndExpand" Margin="20,0,0,0" />
                 <Label Text="&#xf005;&#xf005;&#xf005;&#xf5c0;&lt;span style=&quot;color:#e2e2e2&quot;&gt;&#xf005;&lt;span&gt;" TextType="Html" TextColor="#ffad00" FontSize="14" Grid.Column="0" Grid.Row="0" VerticalOptions="End" HorizontalOptions="EndAndExpand" Margin="0,0,20,0">
                    <Label.FontFamily>
                        <OnPlatform x:TypeArguments="x:String" Android="Font-Awesome-Free-Solid.otf#FontAwesome5Free-Solid" iOS="FontAwesome5Free-Solid" />
                    </Label.FontFamily>
                 </Label>
                 <Label x:Name="xTitulo" FontAttributes="Bold" TextColor="#337760" FontSize="20" Grid.Column="0" Grid.Row="1" VerticalOptions="StartAndExpand" HorizontalOptions="StartAndExpand" Margin="20,0,0,0"></Label>
                 <Label x:Name="xEndereco" TextColor="#8e8e8e" FontSize="12" Grid.Column="0" Grid.Row="2" VerticalOptions="StartAndExpand" HorizontalOptions="StartAndExpand" Margin="20,0,0,0"></Label>

                 <Frame VerticalOptions="Fill" Grid.Column="0" Grid.Row="3" CornerRadius="4" Padding="0" Margin="10,5,10,5">
                    <Image x:Name="ImagemCapa" HorizontalOptions="FillAndExpand" Aspect="AspectFill" VerticalOptions="FillAndExpand" />
                 </Frame>

                 <controls:BotaoFrame Grid.Column="0" Grid.Row="4" BackgroundColor="#198B61" Margin="10,0,10,0" Padding="0" CornerRadius="4">
                     <controls:BotaoFrame.GestureRecognizers>
                         <TapGestureRecognizer Tapped="Button_Clicked" />
                     </controls:BotaoFrame.GestureRecognizers>
                     <Grid HorizontalOptions="CenterAndExpand">
                         <Grid.ColumnDefinitions>
                             <ColumnDefinition Width="auto"></ColumnDefinition>
                             <ColumnDefinition Width="*"></ColumnDefinition>
                         </Grid.ColumnDefinitions>
                         <Grid.RowDefinitions>
                             <RowDefinition Height="*"></RowDefinition>
                         </Grid.RowDefinitions>
                         <Label Grid.Column="0" Grid.Row="0" Text="&#xf086;" TextColor="White" FontSize="22" VerticalOptions="CenterAndExpand">
                         <Label.FontFamily>
                            <OnPlatform x:TypeArguments="x:String" Android="Font-Awesome-Free-Solid.otf#FontAwesome5Free-Solid" iOS="FontAwesome5Free-Solid" />
                        </Label.FontFamily>
                         </Label>
                         <Label Grid.Column="1" Grid.Row="0" Text="tire dúvidas e agende um atendimento" TextColor="White" FontSize="14" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" />                         
                     </Grid>
                 </controls:BotaoFrame>

                 <!-- ESPECIALIDADES -->
                <Grid Grid.Row="5" Grid.Column="0" VerticalOptions="StartAndExpand">
                 <FlexLayout x:Name="xEspecialidades" BindableLayout.ItemsSource="{Binding especialidades}" VerticalOptions="Fill" Margin="10,15,10,5" JustifyContent="Start" AlignContent="Start" AlignItems="Stretch" AlignSelf="Center" Wrap="Wrap" HorizontalOptions="FillAndExpand">
                    <BindableLayout.ItemTemplate>
                        <DataTemplate>
                            <Grid HeightRequest="20" Margin="0,0,4,6" HorizontalOptions="StartAndExpand">
                                <Frame BackgroundColor="#f1f1f1" CornerRadius="5" Padding="2" HorizontalOptions="StartAndExpand">
                                   <Label Text="{Binding .}" Grid.Column="1" Grid.Row="0" TextColor="DarkGray" FontSize="11" HorizontalOptions="Fill" />
                                </Frame>
                            </Grid>
                          </DataTemplate>
                    </BindableLayout.ItemTemplate>
                  </FlexLayout>
                </Grid>

                 <!-- DISTANCIA -->
                 <Grid x:Name="xGridDistancia" Grid.Column="0" Grid.Row="6" VerticalOptions="StartAndExpand" HorizontalOptions="CenterAndExpand">
                         <Grid.ColumnDefinitions>
                             <ColumnDefinition Width="auto"></ColumnDefinition>
                             <ColumnDefinition Width="auto"></ColumnDefinition>
                         </Grid.ColumnDefinitions>
                         <Grid.RowDefinitions>
                             <RowDefinition Height="40"></RowDefinition>
                         </Grid.RowDefinitions>

                         <Label Grid.Column="0" Grid.Row="0" Text="&#xf3c5;" TextColor="#ff4800" FontSize="22" VerticalOptions="CenterAndExpand">
                         <Label.FontFamily>
                            <OnPlatform x:TypeArguments="x:String" Android="Font-Awesome-Free-Solid.otf#FontAwesome5Free-Solid" iOS="FontAwesome5Free-Solid" />
                        </Label.FontFamily>
                     </Label>
                     <Label x:Name="xDistancia" Grid.Column="1" Grid.Row="0" TextType="Html" TextColor="#505050" FontSize="14" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" />
                 </Grid>

                 <!-- MAPA -->
                 <Frame x:Name="MapaFrame" Grid.Column="0" Grid.Row="7" Padding="0" Margin="0" HasShadow="False" HorizontalOptions="Fill" VerticalOptions="Fill">
                     <maps:Map x:Name="Mapa"
                               MapType="Street"
                               VerticalOptions="FillAndExpand"
                               HorizontalOptions="FillAndExpand" 
                               IsShowingUser="true">
                     </maps:Map>
                 </Frame>

                 <Label x:Name="xSobreTitulo" Grid.Row="8" Grid.Column="0" TextColor="#58C8A2" FontSize="Title" Margin="10,10,10,10" />
                 <Label x:Name="xSobreTexto" LineBreakMode="WordWrap" TextType="Html" Grid.Row="9" Grid.Column="0" TextColor="Black" Margin="10,10,10,10" />

                 <!-- SLIDE IMAGENS -->
                 <CollectionView HeightRequest="110" Grid.Row="10" Grid.Column="0" x:Name="ImagensCollection" x:FieldModifier="public static" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" VerticalScrollBarVisibility="Never" HorizontalScrollBarVisibility="Never">
                     <CollectionView.ItemsLayout>
                        <LinearItemsLayout Orientation="Horizontal" SnapPointsType="Mandatory" SnapPointsAlignment="Start" />
                     </CollectionView.ItemsLayout>

                     <CollectionView.ItemTemplate>
                        <DataTemplate>
                            <Frame Padding="5">
                                <Frame.GestureRecognizers>
                                    <TapGestureRecognizer Command="{Binding ImageZoom}" CommandParameter="{Binding keyname}" />
                                </Frame.GestureRecognizers>
                                <Frame HeightRequest="100" WidthRequest="100" BackgroundColor="Transparent" CornerRadius="4" Padding="0" Margin="0">
                                    <Image Source="{Binding keyname, StringFormat='www.myapp/assets/libs/thumb.php?w=300&#x26;h=300&#x26;img={0}'}"  HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Aspect="AspectFill" />
                                </Frame>
                            </Frame>
                        </DataTemplate>
                    </CollectionView.ItemTemplate>
                </CollectionView>

                 <!-- CURRICULUM E PAGAMENTOS -->
                 <Grid Grid.Row="11" Grid.Column="0" VerticalOptions="StartAndExpand">
                 <FlexLayout x:Name="xCurriculum" BindableLayout.ItemsSource="{Binding curriculum}" VerticalOptions="Fill" Margin="10,15,10,5" JustifyContent="Start" Wrap="Wrap" HorizontalOptions="FillAndExpand">
                    <BindableLayout.ItemTemplate>
                        <DataTemplate>
                            <Grid HeightRequest="20" Margin="0,0,4,6" HorizontalOptions="StartAndExpand">
                                <Frame BackgroundColor="#f1f1f1" CornerRadius="5" Padding="2" HorizontalOptions="StartAndExpand">
                                    <Grid HeightRequest="20" Margin="0" Padding="0">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="auto" />
                                            <ColumnDefinition Width="auto" />
                                        </Grid.ColumnDefinitions>
                                        <Grid.RowDefinitions><RowDefinition Height="20" /></Grid.RowDefinitions>

                                        <Label VerticalOptions="CenterAndExpand" Grid.Column="0" Grid.Row="0" Text="&#xf559;" TextColor="DarkGray" FontSize="12">
                                             <Label.FontFamily>
                                                <OnPlatform x:TypeArguments="x:String" Android="Font-Awesome-Free-Solid.otf#FontAwesome5Free-Solid" iOS="FontAwesome5Free-Solid" />
                                            </Label.FontFamily>
                                         </Label>
                                        <Label VerticalOptions="CenterAndExpand" Text="{Binding .}" Grid.Column="1" Grid.Row="0" TextColor="DarkGray" FontSize="11" HorizontalOptions="Fill" />

                                    </Grid>
                                </Frame>
                            </Grid>
                          </DataTemplate>
                    </BindableLayout.ItemTemplate>
                  </FlexLayout>
                </Grid>

             </Grid>
         </ScrollView>
     </Grid>
  </ContentPage.Content>
</ContentPage>

controls:BotaoFrame 是一个实现 Frame 的简单类,但具有图案化视觉效果,我确信这与问题无关

隐藏代码:

using Xamarin.Forms;
using Xamarin.Forms.Maps;
using System.Collections.ObjectModel;
using System;
using MasterDetailPageNavigation.XAML;
using System.Threading.Tasks;

namespace MasterDetailPageNavigation
{
    public partial class VisualizarProfissional : ContentPage
    {
        public static ProfissionalVer dados = null;
        public static ObservableCollection<string> EspecialidadesLista;
        public string IdProfGlobal;
        public VisualizarProfissional(string IdProf)
        {
            InitializeComponent();
            NavigationPage.SetHasNavigationBar(this, false);
            NavigationPage.SetHasBackButton(this, false);
            IdProfGlobal = IdProf;
            Task.Run(()=>GetProfissionalData(IdProf));
        }

        public async Task GetProfissionalData(string id)
        {
            WebService client = new WebService();
            dados = await Task.Run(()=> client.GetJsonUnique<ProfissionalVer>("wwwmyapp.com/assets/libs/app/VisualizarProfissional.php?id=" + id));

            if (dados != null)
            {
                xCategoria.Text = dados.contaTipo == 3 ? dados.estabelecimento : dados.profissao;
                xTitulo.Text = dados.titulo;
                xEspecialidades.BindingContext = dados;
                xCurriculum.BindingContext = dados;

                xEndereco.Text = dados.privLocal == 0 ? (
                    (dados.logradouro != null ? dados.logradouro : "") +
                    (dados.imovelN != null ? ", " + dados.imovelN : "") +
                    (dados.complemento != null ? " - " + dados.complemento : "") +
                    (dados.bairro != null ? ", " + dados.bairro : "") +
                    (dados.cidade != null ? ", " + dados.cidade : "") +
                    (dados.uf != null ? " " + dados.uf : "")
                    ) : dados.bairro + " - " + dados.cidade + " " + dados.uf;

                // Imagens
                if (dados.imagens.Count > 0)
                {
                    ImagemCapa.Source = "wwwmyapp.com/assets/libs/thumb.php?w=300&h=300&img=" + dados.imagens[0].keyname;
                    if (dados.imagens.Count > 1)
                    {
                        ImagensCollection.ItemsSource = dados.imagens;
                        ImagensCollection.IsVisible = true;
                    }
                }
                else
                {
                    ImagemCapa.Source = "semimage.jpg";
                    ImagensCollection.IsVisible = false;
                }

                //Mapa e distancia
                if (ContactsPage.PubCoords.Latitude != null && ContactsPage.PubCoords.Longitude != null
                    && dados.lat != null && dados.lng != null)
                {
                    double lat1 = ContactsPage.PubCoords.Latitude;
                    double lon1 = ContactsPage.PubCoords.Longitude;
                    double lat2 = dados.lat;
                    double lon2 = dados.lng;

                    double rlat1 = Math.PI * lat1 / 180;
                    double rlat2 = Math.PI * lat2 / 180;
                    double theta = lon1 - lon2;
                    double rtheta = Math.PI * theta / 180;
                    double dist =
                        Math.Sin(rlat1) * Math.Sin(rlat2) + Math.Cos(rlat1) *
                        Math.Cos(rlat2) * Math.Cos(rtheta);
                    dist = Math.Acos(dist);
                    dist = dist * 180 / Math.PI;
                    dist = dist * 60 * 1.1515 * 1.609344;

                    string distShow;
                    if (dist < 1)
                    {
                        dist = dist * 1000;
                        distShow = string.Format("{0:0.0}", dist);
                        if (distShow == "0.0")
                            distShow = "Parece que você chegou ao endereço!";
                        else
                            distShow = "Aproximadamente <strong>" + distShow + " metros</strong> de você";
                    }
                    else
                    {
                        distShow = "Aproximadamente <strong>" + string.Format("{0:0.0}", dist) + " km</strong> de você";
                    }

                    xDistancia.Text = distShow;

                    if (dados.privLocal == 1)
                    {
                        RowMap.Height = 0;
                        MapaFrame.IsVisible = false;
                    }
                }
                else
                {
                    xGridDistancia.IsVisible = false;
                }

                if (dados.lat != null && dados.lng != null && dados.privLocal == 0)
                {
                    Mapa.MoveToRegion(MapSpan.FromCenterAndRadius(
                        new Position(dados.lat, dados.lng),
                        Distance.FromMiles(0.5)));

                    var pin = new Pin
                    {
                        Type = PinType.Place,
                        Position = new Position(dados.lat, dados.lng),
                        Label = dados.titulo,
                        Address = dados.logradouro,
                    };

                    Mapa.Pins.Add(pin);
                }
                else if (dados.privLocal == 1)
                {
                    MapaFrame.IsVisible = false;
                    Mapa.IsEnabled = false;
                    RowMap.Height = 0;
                }

                // Sobre
                if (dados.sobre != null)
                {
                    xSobreTitulo.Text = "Sobre - " + dados.titulo;
                    xSobreTexto.Text = "<p style ='text-align:justify;'>" + dados.sobre + "</p>";
                }
                else
                {
                    xSobreTitulo.IsVisible = false;
                    xSobreTexto.IsVisible = false;
                }

            }
            else
                GetProfissionalData(id);

        }

        async void Button_Clicked(System.Object sender, System.EventArgs e)
        {
            if (App.Current.MainPage is MasterDetailPage mdp)
            {
                await mdp.Detail.Navigation.PushAsync(new SecondPage(IdProfGlobal));
                mdp.IsPresented = false;
            }
        }
    }
}

所有页面似乎都有这个问题,这只是我想公开的一个示例页面,看看我是否做错了(笑)。 有人看出这个问题的原因是什么吗?

最佳答案

尽管它有所帮助,但主要问题并不在这个特定页面中。主页是问题所在,它有

<StackLayout><ScrollView></ScrollView></StackLayout>

我只需删除 <StackLayout></StackLayout>现在整个应用程序中的一切都运行顺利。这证明了构建干净的布局是多么重要。

关于c# - 为什么滚动这个 xamarin 页面这么慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61959284/

相关文章:

android - 在 Google Maps API 中设置标记图标

java - 在 Java 中实现固定大小的非阻塞队列的最有效方法是什么?

C#:与内联代码相比,使用多个函数执行速度如何?

c# - WinForms/C# 中的动画效果

c# - 类(class)创作设计。需要一些帮助

ruby 数组#bsearch : operation and returning nil when value is not in Array

xamarin - Xamarin 中的 WebView 内部深度链接

uiviewcontroller - ShouldAutorotate 和 GetSupportedInterfaceOrientations 未在 Xamarin.iOS 中调用

c# - StackExchange.Redis 对配置的 Masters/Slaves 做了什么?

c# - 为什么 HttpContext.Current 在使用 ConfigureAwait 的 async/await 中不为 null