为啥滚动这个 xamarin 页面这么慢?
Posted
技术标签:
【中文标题】为啥滚动这个 xamarin 页面这么慢?【英文标题】:Why is scrolling this xamarin page so slow?为什么滚动这个 xamarin 页面这么慢? 【发布时间】:2020-09-09 13:05:56 【问题描述】:我正在开发一个 xamarin 项目(android,尚未在 ios 中测试),并注意到我的 UI 在滚动时很慢(scrollview / observablecollection)。我在Xamarin official page 阅读了一些关于性能的建议,并尝试过,还进行了其他测试,但没有任何收获。
当用户尝试滚动某些东西时,感觉好像它正在反复快速冻结/释放用户界面。
这是我为测试目的而尝试的,但没有成功:
移除地图 将图像更改为 ffimageloading 缓存图像 移除标签 删除了不必要的 StackLayouts 从滚动视图标签中删除了 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="<span style="color:#e2e2e2"><span>" 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="" 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="" 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&h=300&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="" 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;
所有页面似乎都有这个问题,这只是我想公开的一个示例页面,看看我是否做错了一切(笑)。 有人知道导致此问题的原因是什么吗?
【问题讨论】:
您是实际将其加载到手机上还是在 PC 上使用模拟器? 我正在我的设备上进行测试:galaxy s6 和 s9。尝试调试和发布版本。 注释掉页面的某些部分并搜索 xaml 块是罪魁祸首 @Mouse 我做到了。我在问题中提到了它。 【参考方案1】:虽然它有所帮助,但主要问题不在于这个特定页面。主页是问题,它有
<StackLayout><ScrollView></ScrollView></StackLayout>
我只需要删除<StackLayout></StackLayout>
,整个应用程序中的所有内容现在都运行顺利。这证明了构建干净的布局是多么重要。
【讨论】:
除此之外,看看 UI 代码,它仍然很复杂,并且包含太多不必要的布局。 感谢您的分享,请采纳您的回答,对有类似问题的其他人有帮助。 不幸的是,这对我们来说不是一个选项,因为 StackLayout 是必需的 - 布局已经很干净了!以上是关于为啥滚动这个 xamarin 页面这么慢?的主要内容,如果未能解决你的问题,请参考以下文章
升级到 Visual Studio 16.11.1 后,Xamarin Forms 破坏了 XANS 7028:System.IO.FileNotFoundException:无法加载程序集“Xama