Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Při psaní mobilních aplikací záleží na výkonu. Uživatelé přišli očekávat hladké posouvání a rychlé načítání. Když se vám nepodaří splnit očekávání vašich uživatelů, budou vám náklady na hodnocení v obchodě s aplikacemi nebo v případě obchodní aplikace stát čas a peníze vaší organizace.
Jedná se Xamarin.FormsListView o výkonné zobrazení pro zobrazení dat, ale má určitá omezení. Při používání vlastních buněk může dojít k snížení výkonu posouvání, zejména pokud obsahují hluboko vnořené hierarchie zobrazení nebo používají určitá rozložení, která vyžadují komplexní měření. Naštěstí existují techniky, které můžete použít, abyste se vyhnuli nízkému výkonu.
Strategie ukládání do mezipaměti
Objekty ListView se často používají k zobrazení mnohem více dat, než se vejde na obrazovku. Hudební aplikace může mít například knihovnu skladeb s tisíci položek. Vytvoření položky pro každou položku by ztrácelo cennou paměť a fungovalo špatně. Vytváření a zničení řádků by neustále vyžadovalo vytvoření instance a vyčištění objektů aplikace, což by také fungovalo špatně.
Pro zachování paměti mají nativní ListView ekvivalenty pro každou platformu integrované funkce pro opakované využití řádků. Do paměti se načtou jenom buňky viditelné na obrazovce a obsah se načte do existujících buněk. Tento model brání aplikaci v vytváření instancí tisíců objektů, což šetří čas a paměť.
Xamarin.FormsListView umožňuje opakované použití buněk prostřednictvím výčtuListViewCachingStrategy, který má následující hodnoty:
public enum ListViewCachingStrategy
{
RetainElement, // the default value
RecycleElement,
RecycleElementAndDataTemplate
}
Poznámka:
Univerzální platforma Windows (UPW) ignoruje RetainElement strategii ukládání do mezipaměti, protože ke zlepšení výkonu vždy používá ukládání do mezipaměti. Ve výchozím nastavení se proto chová jako při RecycleElement použití strategie ukládání do mezipaměti.
ZachovatElement
Strategie RetainElement ukládání do mezipaměti určuje, že ListView se pro každou položku v seznamu vygeneruje buňka a že se jedná o výchozí ListView chování. Měla by být použita za následujících okolností:
- Každá buňka má velký počet vazeb (20-30+).
- Šablona buňky se často mění.
- Testování ukazuje, že
RecycleElementstrategie ukládání do mezipaměti vede ke snížení rychlosti provádění.
Při práci s vlastními buňkami je důležité rozpoznat důsledky RetainElement strategie ukládání do mezipaměti. Každý inicializační kód buňky bude potřeba spustit pro každé vytvoření buňky, což může být několikrát za sekundu. V této situaci se techniky rozložení, které byly na stránce v pořádku, jako je použití více vnořených StackLayout instancí, stanou kritickými body výkonu při jejich nastavení a zničení v reálném čase při posouvání uživatele.
RecycleElement
Strategie RecycleElement ukládání do mezipaměti určuje, že ListView se pokusí minimalizovat nároky na paměť a rychlost spouštění díky recyklaci buněk seznamu. Tento režim nenabízí vždy zlepšení výkonu a testování by se mělo provést, aby bylo možné určit všechna vylepšení. Je to ale upřednostňovaná volba a měla by se použít za následujících okolností:
- Každá buňka má malý až střední počet vazeb.
- Každá buňka
BindingContextdefinuje všechna data buněk. - Každá buňka je z velké části podobná a šablona buňky se nemění.
Během virtualizace bude mít buňka aktualizovaný kontext vazby, takže pokud aplikace používá tento režim, musí zajistit, aby aktualizace kontextu vazby byly zpracovány odpovídajícím způsobem. Všechna data o buňce musí pocházet z kontextu vazby nebo mohou nastat chyby konzistence. Tento problém lze vyhnout pomocí datové vazby k zobrazení dat buňky. Další možností je nastavit data buňky v OnBindingContextChanged přepsání, nikoli v konstruktoru vlastní buňky, jak je znázorněno v následujícím příkladu kódu:
public class CustomCell : ViewCell
{
Image image = null;
public CustomCell ()
{
image = new Image();
View = image;
}
protected override void OnBindingContextChanged ()
{
base.OnBindingContextChanged ();
var item = BindingContext as ImageItem;
if (item != null) {
image.Source = item.ImageUrl;
}
}
}
Další informace naleznete v tématu Změny kontextu vazby.
Pokud buňky v iOSu a Androidu používají vlastní renderery, musí zajistit správnou implementaci oznámení o změně vlastnosti. Při opakovaném použití buněk se hodnoty vlastností změní při aktualizaci kontextu vazby na dostupnou buňku s PropertyChanged vyvoláním událostí. Další informace naleznete v tématu Přizpůsobení ViewCell.
RecycleElement s objektem DataTemplateSelector
ListView Pokud se použije DataTemplateSelector k výběru , DataTemplateRecycleElement strategie ukládání do mezipaměti neukládá mezipamětiDataTemplate. DataTemplate Místo toho je vybrána pro každou položku dat v seznamu.
Poznámka:
Strategie RecycleElement ukládání do mezipaměti má předpoklad zavedený ve Xamarin.Forms verzi 2.4, že když DataTemplateSelector se zobrazí výzva k výběru DataTemplate , který musí každý DataTemplate vrátit stejný ViewCell typ. Pokud je například vrácena ListView hodnota typu DataTemplateSelector , která může vrátit buď MyDataTemplateA (kde MyDataTemplateA vrátí ViewCell typ MyViewCellA), nebo MyDataTemplateB (kde MyDataTemplateB vrátí ViewCell typ MyViewCellB), když MyDataTemplateA je vrácena, musí vrátit MyViewCellA nebo se vyvolá výjimka.
RecycleElementAndDataTemplate
Strategie RecycleElementAndDataTemplate ukládání do mezipaměti je založená na RecycleElement strategii ukládání do mezipaměti tím, že navíc zajišťuje, že když ListView se použije DataTemplateSelector k výběru , DataTemplateDataTemplatebudou uloženy v mezipaměti podle typu položky v seznamu. DataTemplateProto jsou vybrány jednou za typ položky místo jednou na instanci položky.
Poznámka:
RecycleElementAndDataTemplate Strategie ukládání do mezipaměti má předpoklad, že DataTemplatevrácené vrácené DataTemplateSelector musí použít DataTemplate konstruktor, který přebírá Type.
Nastavení strategie ukládání do mezipaměti
Hodnota ListViewCachingStrategy výčtu je zadána s přetížením konstruktoru ListView , jak je znázorněno v následujícím příkladu kódu:
var listView = new ListView(ListViewCachingStrategy.RecycleElement);
V JAZYCE XAML nastavte CachingStrategy atribut, jak je znázorněno v následujícím kódu XAML:
<ListView CachingStrategy="RecycleElement">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
...
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Tato metoda má stejný účinek jako nastavení argumentu strategie ukládání do mezipaměti v konstruktoru v jazyce C#.
Nastavení strategie ukládání do mezipaměti v podtřídě ListView
Nastavení atributu CachingStrategy z XAML v podtřídě ListView nevyvolá požadované chování, protože neexistuje žádná CachingStrategy vlastnost ListView. Kromě toho, pokud je povolen XAMLC , bude vytvořena následující chybová zpráva: Žádná vlastnost, bindable vlastnost nebo událost nalezena pro 'CachingStrategy'
Řešením tohoto problému je zadat konstruktor v podtřídě ListView , který přijímá ListViewCachingStrategy parametr a předává ho do základní třídy:
public class CustomListView : ListView
{
public CustomListView (ListViewCachingStrategy strategy) : base (strategy)
{
}
...
}
Potom lze hodnotu výčtu ListViewCachingStrategy zadat z XAML pomocí x:Arguments syntaxe:
<local:CustomListView>
<x:Arguments>
<ListViewCachingStrategy>RecycleElement</ListViewCachingStrategy>
</x:Arguments>
</local:CustomListView>
Návrhy výkonu ListView
Existuje mnoho technik pro zlepšení výkonu ListView. Následující návrhy můžou zlepšit výkon zobrazení ListView.
ItemsSourceVytvořte vazbu vlastnosti naIList<T>kolekci místoIEnumerable<T>kolekce, protožeIEnumerable<T>kolekce nepodporují náhodný přístup.- Místo toho používejte předdefinované buňky (například
TextCell/SwitchCell) místoViewCelltoho, abyste je mohli použít. - Používejte méně prvků. Zvažte například použití jednoho
FormattedStringpopisku místo více popisků. ListViewNahraďte hoTableViewpři zobrazení nehomogenních dat – to znamená dat různých typů.- Omezte použití
Cell.ForceUpdateSizemetody. Pokud dojde k nadměrnému výkonu, sníží se výkon. - V Androidu se vyhněte nastavení
ListViewviditelnosti nebo barvy oddělovače řádků po vytvoření instance, protože výsledkem je velký výkon. - Vyhněte se změně rozložení buňky na základě .
BindingContextZměna rozložení způsobuje velké náklady na měření a inicializaci. - Vyhněte se hluboko vnořeným hierarchií rozložením. Použijte
AbsoluteLayoutneboGridpomozte snížit vnoření. - Vyhněte se jiným než
LayoutOptionsFill(Fillje nejlevnější pro výpočty). - Vyhněte se umístění
ListViewuvnitř zScrollViewnásledujících důvodů:- Implementuje
ListViewvlastní posouvání. - Nebudou
ListViewpřijímat žádná gesta, protože bude zpracována nadřazenýmScrollViewobjektem . - Může
ListViewprezentovat přizpůsobené záhlaví a zápatí, které se posune s prvky seznamu, a potenciálně nabízí funkce, pro kteréScrollViewbyl použit. Další informace najdete v tématu Záhlaví a zápatí.
- Implementuje
- Pokud potřebujete konkrétní komplexní návrh zobrazený v buňkách, zvažte vlastní renderer.
AbsoluteLayout má potenciál provádět rozložení bez jediného volání míry, což z něj dělá vysoce výkonné. Pokud AbsoluteLayout nelze použít, zvažte RelativeLayout. Pokud používáte RelativeLayout, předávání omezení přímo bude výrazně rychlejší než použití rozhraní API pro výrazy. Tato metoda je rychlejší, protože rozhraní API výrazů používá JIT a v iOSu je potřeba strom interpretovat, což je pomalejší. Rozhraní API výrazu je vhodné pro rozložení stránek, kde se vyžaduje pouze při počátečním rozložení a otočení, ale v místě, kde ListViewse při posouvání spouští neustále, snižuje výkon.
Vytvoření vlastního rendereru ListView pro buňky nebo jeho buněk je jedním z přístupů ke snížení vlivu výpočtů rozložení při posouvání výkonu. Další informace naleznete v tématu Přizpůsobení objektu ListView a přizpůsobení objektu ViewCell.