Vytvoření vlastního rozložení v Xamarin.Forms
Xamarin.Forms definuje pět tříd rozložení – StackLayout, AbsoluteLayout, RelativeLayout, Grid aLayout a každá z nich uspořádá své děti jiným způsobem. Někdy je ale potřeba uspořádat obsah stránky pomocí rozložení, které neposkytuje Xamarin.FormsXamarin.Forms . Tento článek vysvětluje, jak napsat třídu vlastního rozložení, a ukazuje třídu WrapLayout citlivou na orientaci, která uspořádá své děti vodorovně přes stránku a následně zabalí zobrazení následných dětí na další řádky.
V systému jsou všechny třídy rozložení odvozeny z třídy a Xamarin.FormsLayout<T> omezují obecný typ na a její odvozené View typy. Třída je zase odvozena z třídy , která poskytuje mechanismus pro umístění a Layout<T>Layout změnu velikosti podřízených elementů.
Každý prvek vizuálu zodpovídá za určení vlastní upřednostňované velikosti, která se označuje jako požadovaná velikost. Page, Layout a odvozené typy zodpovídají za určení umístění a velikosti jejich podřízených nebo podřízených objektů Layout<View> vzhledem k sobě. Rozložení proto zahrnuje vztah nadřazenosti a podřízené položky, kde nadřazený objekt určuje, jaká má být velikost podřízených prvků, ale pokusí se pojmout požadovanou velikost podřízeného prvku.
K vytvoření vlastního rozložení je potřeba důkladné porozumění cyklům rozložení Xamarin.Forms a zneplatnění. O těchto cyklech se teď budeme diskutovat.
Layout
Rozložení začíná v horní části vizuálního stromu stránkou a pokračuje všemi větvemi vizuálního stromu, aby zahrnovaly každý vizuální prvek na stránce. Prvky, které jsou rodičům jiných prvků, zodpovídají za nastavení velikosti a umístění svých dětí vzhledem k sobě.
Třída definuje metodu VisualElement Xamarin_Forms VisualElement _VisualElement_Measure_System_Double_System_Double_ Xamarin_Forms _MeasureFlags_" data-linktype="absolute-path">, která měří element pro operace Measure rozložení, a Xamarin_Forms _VisualElement_Layout_ Xamarin_Forms _Rectangle_" data-linktype="absolute-path">Layout metoda, která určuje obdélníkovou oblast, ve které bude prvek vykreslen. Když se spustí aplikace a zobrazí se první stránka, spustí se cyklus rozložení, který se skládá nejprve z volání a pak volá , u objektu LayoutPage :
- Během cyklu rozložení zodpovídá za volání metody u podřízených elementů
Measurekaždý nadřazený prvek. - Po změřování podřízených prvků zodpovídá za volání metody u
Layoutpodřízených prvků každý nadřazený prvek.
Tento cyklus zajišťuje, že každý prvek vizuálu na stránce přijímá volání metod MeasureLayout a . Postup je znázorněn v následujícím diagramu:
Cyklus rozložení Xamarin.Forms" 
Poznámka
Všimněte si, že cykly rozložení mohou také nastat u podmnožiny vizuálního stromu, pokud se něco změní, aby to ovlivnilo rozložení. To zahrnuje přidání nebo odebrání položek z kolekce, například v , změnu v StackLayout Xamarin_Forms StackLayout _VisualElement_IsVisible" data-linktype="absolute-path">vlastnost elementu nebo změnu velikosti IsVisible prvku.
Každá třída, která má vlastnost nebo , má přepisovatelný Xamarin_Forms Xamarin.FormsContentChildrenXamarin.Forms _Layout_LayoutChildren_System_Double_System_Double_System_Double_System_Double_" data-linktype="absolute-path">LayoutChildren metoda. Vlastní třídy rozložení, které jsou odvozeny z , musí tuto metodu přepsat a zajistit, aby metody Layout<View> Xamarin_Forms Layout<View> _VisualElement_Measure_System_Double_System_Double_ Xamarin_Forms _MeasureFlags_" data-linktype="absolute-path">a Measure Xamarin_Forms _VisualElement_Layout_ Xamarin_Forms _Rectangle_" data-linktype="absolute-path">Layout byly volány u všech podřízených elementů, aby bylo možné poskytnout požadované vlastní rozložení.
Kromě toho každá třída odvozená z nebo musí přepsat Xamarin_Forms _VisualElement_OnMeasure_System_Double_System_Double_" data-linktype="absolute-path">, což je místo, kde třída rozložení určuje velikost, kterou potřebuje, voláním LayoutLayout<View> metody Xamarin_Forms _VisualElement_Measure_System_Double_System_Double_ LayoutOnMeasureLayout<View>Xamarin_Forms _MeasureFlags_" data-linktype="absolute-path">Measure metod svých dětí.
Poznámka
Elementy určují jejich velikost na základě omezení, které označují, kolik místa je k dispozici pro prvek v rámci nadřazeného prvku. Omezení předaná metodám Xamarin_Forms _VisualElement_Measure_System_Double_System_Double_ Xamarin_Forms _MeasureFlags_" data-linktype="absolute-path">and Measure Xamarin_Forms Xamarin_Forms _VisualElement_OnMeasure_System_Double_System_Double_" data-linktype="absolute-path">OnMeasureDouble.PositiveInfinity může být v rozsahu od 0 do . Element je omezen ,nebo plně omezený,když přijme volání své Xamarin_Forms metoda s nenekonečnou argumenty – element je omezen na konkrétní velikost. Element je neomezené nebo částečně omezený,když přijme volání své metody s alespoň jedním argumentem, který je roven – nekonečné omezení lze nazývat automatické velikosti.
Neplatnost
Zneplatnění je proces, při kterém změna elementu na stránce aktivuje nový cyklus rozložení. Prvky se považují za neplatné, pokud už nemají správnou velikost nebo pozici. Pokud například Xamarin_Forms _Button_FontSize" data-linktype="absolute-path">změny, bude se říká, že je neplatný, protože už nebude mít FontSizeButtonButton správnou velikost. Změna velikosti Button pak může mít zvlněný efekt změn v rozložení po zbytek stránky.
Prvky se zneplatní vyvoláním metody Xamarin_Forms _VisualElement_InvalidateMeasure" data-linktype="absolute-path">, obecně v případě změny vlastnosti prvku, která může vést k nové velikosti InvalidateMeasure elementu. Tato metoda aktivuje událost, kterou nadřazený prvek zpracovává, aby MeasureInvalidated se spouštěl nový cyklus rozložení.
Třída nastaví obslužnou rutinu pro událost u každého podřízeného objektu přidaného do své vlastnosti nebo kolekce a odpojí obslužnou rutinu při LayoutMeasureInvalidated odebrání ContentChildren podřízeného objektu. Každý prvek ve vizuálním stromu, který obsahuje podřízený prvek, je proto upozorněn vždy, když jedna z podřízených prvků změní velikost. Následující diagram znázorňuje, jak může změna velikosti prvku ve vizuálním stromu způsobit změny, které strom rozklenou:

Třída se však pokusí omezit dopad změny velikosti podřízeného na Layout rozložení stránky. Pokud je rozložení omezené velikostí, pak změna podřízené velikosti nemá vliv na nic vyššího než nadřazené rozložení ve vizuálním stromu. Obvykle ale změna velikosti rozložení ovlivňuje způsob, jakým rozložení uspořádá své děti. Proto jakákoli změna velikosti rozložení spustí cyklus rozložení a rozložení bude přijímat volání jeho Xamarin_Forms _VisualElement_OnMeasure_System_Double_System_Double_" data-linktype="absolutní_cesta">a Xamarin_Forms OnMeasureOnMeasure _Layout_LayoutChildren_System_Double_System_Double_System_Double_System_Double_" data-linktype="absolutní_cesta">LayoutChildren metody.
Třída také definuje metodu Layout Xamarin_Forms Layout _Layout_InvalidateLayout" data-linktype="absolute-path">, která má podobný účel jako InvalidateLayout metoda Xamarin_Forms _VisualElement_InvalidateMeasure" data-linktype="absolute-path">. InvalidateMeasure Metoda InvalidateLayout by měla být vyvolána při každé změně, která má vliv na umístění rozložení a velikost jejích dětí. Například třída vyvolá metodu pokaždé, když je do rozložení přidána nebo LayoutInvalidateLayout odebrána podřízený objekt.
Metodu Xamarin_Forms _Layout_InvalidateLayout" data-linktype="absolute-path">je možné přepsat implementací mezipaměti, aby se minimalizovala opakovaná volání Xamarin_Forms _VisualElement_Measure_System_Double_System_Double_ InvalidateLayoutInvalidateLayoutXamarin_Forms _MeasureFlags_" data-linktype="absolute-path">Measure metod dětí rozložení. Přepsáním metody se zobrazí oznámení o tom, kdy se do rozložení přidávají nebo InvalidateLayout odebraly děti. Podobně lze Xamarin_Forms _Layout_OnChildMeasureInvalidated" data-linktype="absolute-path">metodu přepsat a poskytnout oznámení, když se změní velikost jedné z dětí OnChildMeasureInvalidated rozložení. U obou přepsání metod by vlastní rozložení mělo reagovat vymazáním mezipaměti. Další informace najdete v tématu Výpočet a ukládání dat rozložení do mezipaměti.
Vytvoření vlastního rozložení
Postup vytvoření vlastního rozložení je následující:
Vytvořte třídu, která je odvozena od třídy
Layout<View>. Další informace najdete v tématu Vytvoření objektu WrapLayout.[nepovinné] Pro všechny parametry, které by měly být nastaveny ve třídě rozložení, přidejte vlastnosti s možností vazby. Další informace najdete v tématu Přidání vlastností pomocí vlastností smožností vazby.
Přepište metodu Xamarin_Forms _VisualElement_OnMeasure_System_Double_System_Double_" data-linktype="absolute-path">, která vyvolá
OnMeasuremetodu Xamarin_FormsOnMeasure_VisualElement_Measure_System_Double_System_Double_ Xamarin_Forms _MeasureFlags_" data-linktype="absolute-path">Measurepro všechny děti rozložení a vrátí požadovanou velikost rozložení. Další informace najdete v tématu Přepsání metody OnMeasure.Přepište metodu Xamarin_Forms _Layout_LayoutChildren_System_Double_System_Double_System_Double_System_Double_" data-linktype="absolute-path">pro vyvolání
LayoutChildrenmetody Xamarin_Forms _VisualElement_Layout_LayoutChildrenXamarin_Forms _Rectangle_" data-linktype="absolute-path">Layoutu všech dětí rozložení. Pokud metodu Xamarin_Forms _VisualElement_Layout_ Xamarin_Forms _Rectangle_" data-linktype="absolute-path">u každého podřízeného objektu v rozložení nevyvolalo, podřízený objekt nikdy nepřijímá správnou velikost neboLayoutpozici, a podřízený objekt se proto na stránce nezobrazí. Další informace najdete v tématu Přepsání metody Layout Zamykač.Poznámka
Při vytváření výčtu podřízených čar v Xamarin_Forms _VisualElement_OnMeasure_System_Double_System_Double_" data-linktype="absolute-path">and
OnMeasureXamarin_FormsOnMeasure_Layout_LayoutChildren_System_Double_System_Double_System_Double_System_Double_" data-linktype="absolute-path">overrides přeskočte všechny podřízené prvky, jejichž vlastnostLayoutChildrenXamarin_Forms _VisualElement_IsVisible" data-linktype="absolute-path">IsVisiblefalseje nastavená na . Tím se zajistí, že vlastní rozložení nezanechá místo pro neviditelné děti.[nepovinné] Přepište metodu tak, aby byla upozorněna na přidání nebo odebrání dětí z rozložení. Další informace najdete v tématu Přepsání metody InvalidateLayout.
[nepovinné] Přepište Xamarin_Forms _Layout_OnChildMeasureInvalidated" data-linktype="absolute-path">, aby byla upozorněna, když jedna z dětí v rozložení změní velikost. Další informace najdete v tématu Přepsání metody OnChildMeasureInvalidated.
Poznámka
Všimněte si, Xamarin_Forms _VisualElement_OnMeasure_System_Double_System_Double_" data-linktype="absolute-path">přepsání nebude vyvoláno, pokud se velikost rozložení řídí nadřazeným rozložením, nikoli podřízenými OnMeasure objekty. Přepsání se však vyvolá, pokud je jedno nebo obě omezení nekonečné nebo pokud třída rozložení má nestandní Xamarin_Forms _View_HorizontalOptions" data-linktype="absolutní_cesta">nebo HorizontalOptions Xamarin_Forms HorizontalOptions _View_VerticalOptions" data-linktype="absolutní_cesta">hodnoty VerticalOptions vlastností. Z tohoto důvodu se přepsání Xamarin_Forms _Layout_LayoutChildren_System_Double_System_Double_System_Double_System_Double_" data-linktype="absolute-path">nemůže spoléhat na podřízené velikosti získané během volání metody LayoutChildren Xamarin_Forms LayoutChildren _VisualElement_OnMeasure_System_Double_System_Double_" data-linktype="absolute-path">. OnMeasure Místo toho musí vyvolat metodu LayoutChildren Xamarin_Forms LayoutChildren _VisualElement_Measure_System_Double_System_Double_ Xamarin_Forms _MeasureFlags_" data-linktype="absolute-path">u dětí rozložení před vyvoláním metody Measure Xamarin_Forms _VisualElement_Layout_ Xamarin_Forms _Rectangle_" data-linktype="absolute-path">. Layout Případně lze velikost dětí získaných v přepsání ukládat do mezipaměti, aby se zabránilo pozdějším voláním v přepsání, ale třída rozložení bude muset vědět, kdy je potřeba velikosti získat OnMeasureMeasureLayoutChildren znovu. Další informace najdete v tématu Výpočet a ukládání dat rozložení do mezipaměti.
Třídu rozložení je pak možné využívat tak, že ji přidáte do třídy a přidáním dětí Page do rozložení. Další informace najdete v tématu o používání objektu WrapLayout.
Vytvoření objektu WrapLayout
Ukázková aplikace ukazuje třídu citlivou na orientaci, která uspořádá své děti vodorovně na stránce a následně zabalí zobrazení následných dětí do WrapLayout dalších řádků.
Třída přidělí pro každou podřízený objekt stejnou velikost místa, která se označuje jako velikost buňky, na základě maximální velikosti WrapLayout podřízených ků. WrapLayout Děti menší než velikost buňky mohou být v buňce umístěné na základě jejich Xamarin_Forms _View_HorizontalOptions" data-linktype="absolutní_cesta">HorizontalOptions a Xamarin_Forms HorizontalOptions _View_VerticalOptions" data-linktype="absolutní_cesta">VerticalOptions hodnoty vlastností.
Definice WrapLayout třídy je znázorněna v následujícím příkladu kódu:
public class WrapLayout : Layout<View>
{
Dictionary<Size, LayoutData> layoutDataCache = new Dictionary<Size, LayoutData>();
...
}
Výpočet a ukládání dat rozložení do mezipaměti
Struktura ukládá data o kolekci dětí v LayoutData řadě vlastností:
VisibleChildCount– počet dětí, které jsou viditelné v rozložení.CellSize– maximální velikost všech dětí přizpůsobená velikosti rozložení.Rows– počet řádků.Columns– počet sloupců.
Pole layoutDataCache se používá k uložení více LayoutData hodnot. Při spuštění aplikace budou dva objekty uloženy do mezipaměti ve slovníku pro aktuální orientaci – jeden pro argumenty omezení přepsání a jeden pro argumenty a pro LayoutDatalayoutDataCacheOnMeasurewidthheightLayoutChildren přepsání. Při otočení zařízení do orientace na šířku se znovu vyvolá přepsání a přepsání, což bude mít za následek ukládání dalších dvou objektů do mezipaměti OnMeasureLayoutChildren ve LayoutData slovníku. Když ale zařízení vracíte do orientace na výšku, nejsou potřeba žádné další výpočty, protože už layoutDataCache mají požadovaná data.
Následující příklad kódu ukazuje metodu , která vypočítá vlastnosti strukturovaného objektu GetLayoutDataLayoutData na základě konkrétní velikosti:
LayoutData GetLayoutData(double width, double height)
{
Size size = new Size(width, height);
// Check if cached information is available.
if (layoutDataCache.ContainsKey(size))
{
return layoutDataCache[size];
}
int visibleChildCount = 0;
Size maxChildSize = new Size();
int rows = 0;
int columns = 0;
LayoutData layoutData = new LayoutData();
// Enumerate through all the children.
foreach (View child in Children)
{
// Skip invisible children.
if (!child.IsVisible)
continue;
// Count the visible children.
visibleChildCount++;
// Get the child's requested size.
SizeRequest childSizeRequest = child.Measure(Double.PositiveInfinity, Double.PositiveInfinity);
// Accumulate the maximum child size.
maxChildSize.Width = Math.Max(maxChildSize.Width, childSizeRequest.Request.Width);
maxChildSize.Height = Math.Max(maxChildSize.Height, childSizeRequest.Request.Height);
}
if (visibleChildCount != 0)
{
// Calculate the number of rows and columns.
if (Double.IsPositiveInfinity(width))
{
columns = visibleChildCount;
rows = 1;
}
else
{
columns = (int)((width + ColumnSpacing) / (maxChildSize.Width + ColumnSpacing));
columns = Math.Max(1, columns);
rows = (visibleChildCount + columns - 1) / columns;
}
// Now maximize the cell size based on the layout size.
Size cellSize = new Size();
if (Double.IsPositiveInfinity(width))
cellSize.Width = maxChildSize.Width;
else
cellSize.Width = (width - ColumnSpacing * (columns - 1)) / columns;
if (Double.IsPositiveInfinity(height))
cellSize.Height = maxChildSize.Height;
else
cellSize.Height = (height - RowSpacing * (rows - 1)) / rows;
layoutData = new LayoutData(visibleChildCount, cellSize, rows, columns);
}
layoutDataCache.Add(size, layoutData);
return layoutData;
}
Metoda GetLayoutData provádí následující operace:
- Určuje, jestli je
LayoutDatapočítaná hodnota už v mezipaměti, a pokud je k dispozici, vrátí ji. - V opačném případě provede výčet všech podřízených objektů a u každého podřízeného zařízení metodu s neomezenou šířkou a výškou a určí maximální velikost
Measurepodřízeného zařízení. - Za předpokladu, že existuje alespoň jeden viditelný podřízený objekt, vypočítá požadovaný počet řádků a sloupců a potom vypočítá velikost buňky pro podřízené objekty na základě rozměrů
WrapLayout. Všimněte si, že velikost buňky je obvykle trochu širší než maximální velikost podřízeného velikosti, ale může být také menší, pokud není dostatečně široká pro nejširší podřízený objekt nebo dostatečně vysoká pro nejvyšší podřízenýWrapLayoutobjekt. - Uloží novou hodnotu
LayoutDatado mezipaměti.
Přidání vlastností podchycených vlastnostmi s možností vazby
Třída definuje vlastnosti a , jejichž hodnoty se používají k oddělení řádků a sloupců v rozložení a které jsou zálohovány vlastnostmi s možností WrapLayoutColumnSpacingRowSpacing vazby. Vázání vlastností je znázorněno v následujícím příkladu kódu:
public static readonly BindableProperty ColumnSpacingProperty = BindableProperty.Create(
"ColumnSpacing",
typeof(double),
typeof(WrapLayout),
5.0,
propertyChanged: (bindable, oldvalue, newvalue) =>
{
((WrapLayout)bindable).InvalidateLayout();
});
public static readonly BindableProperty RowSpacingProperty = BindableProperty.Create(
"RowSpacing",
typeof(double),
typeof(WrapLayout),
5.0,
propertyChanged: (bindable, oldvalue, newvalue) =>
{
((WrapLayout)bindable).InvalidateLayout();
});
Obslužná rutina změněná vlastností každé vlastnosti s možností vazby vyvolá přepsání metody pro aktivaci nového předání InvalidateLayout rozložení objektu WrapLayout . Další informace naleznete v části Override the InvalidateLayout Method and Override the OnChildMeasureInvalidated Method.
Přepsání metody OnMeasure
Přepsání OnMeasure je znázorněno v následujícím příkladu kódu:
protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint)
{
LayoutData layoutData = GetLayoutData(widthConstraint, heightConstraint);
if (layoutData.VisibleChildCount == 0)
{
return new SizeRequest();
}
Size totalSize = new Size(layoutData.CellSize.Width * layoutData.Columns + ColumnSpacing * (layoutData.Columns - 1),
layoutData.CellSize.Height * layoutData.Rows + RowSpacing * (layoutData.Rows - 1));
return new SizeRequest(totalSize);
}
Přepsání vyvolá metodu a vytvoří objekt z vrácených dat a zároveň bere v úvahu GetLayoutDataSizeRequest hodnoty RowSpacingColumnSpacing vlastností a . Další informace o metodě GetLayoutData najdete v tématu Výpočet a ukládání dat rozložení do GetLayoutData
Důležité
Metody Xamarin_Forms _VisualElement_Measure_System_Double_System_Double_ Xamarin_Forms _MeasureFlags_" data-linktype="absolute-path">Measure a Xamarin_Forms Xamarin_Forms _VisualElement_OnMeasure_System_Double_System_Double_" data-linktype="absolute-path">OnMeasureSizeRequestDouble.PositiveInfinity by nikdy neměly požadovat nekonečnou dimenzi vrácením hodnoty s vlastností nastavenou na . Alespoň jeden z argumentů omezení na ale OnMeasure může být Double.PositiveInfinity .
Přepsání metody Layout Zachytátka
Přepsání LayoutChildren je znázorněno v následujícím příkladu kódu:
protected override void LayoutChildren(double x, double y, double width, double height)
{
LayoutData layoutData = GetLayoutData(width, height);
if (layoutData.VisibleChildCount == 0)
{
return;
}
double xChild = x;
double yChild = y;
int row = 0;
int column = 0;
foreach (View child in Children)
{
if (!child.IsVisible)
{
continue;
}
LayoutChildIntoBoundingRegion(child, new Rectangle(new Point(xChild, yChild), layoutData.CellSize));
if (++column == layoutData.Columns)
{
column = 0;
row++;
xChild = x;
yChild += RowSpacing + layoutData.CellSize.Height;
}
else
{
xChild += ColumnSpacing + layoutData.CellSize.Width;
}
}
}
Přepsání začíná voláním metody a pak vytvoří výčet všech podřízených objektů pro jejich velikost a umístění v rámci každé podřízené GetLayoutData buňky. Toho se dosáhne vyvoláním metody Xamarin_Forms _Layout_LayoutChildIntoBoundingRegion_ _VisualElement_ _Rectangle_" data-linktype="absolute-path">, která slouží k umístění podřízeného prvku v obdélníku na základě jeho Xamarin_FormsXamarin_Forms Xamarin_Forms LayoutChildIntoBoundingRegionXamarin_Forms _View_HorizontalOptions" data-linktype="absolutní_cesta">HorizontalOptions a Xamarin_Forms Xamarin_Forms _View_VerticalOptions" data-linktype="absolute-path">VerticalOptions hodnoty vlastností. Jedná se o ekvivalent volání metody Xamarin_Forms _VisualElement_Layout_ Xamarin_Forms _Rectangle_" data-linktype="absolute-path">Layout metoda.
Poznámka
Všimněte si, že obdélník předaný LayoutChildIntoBoundingRegion metodě zahrnuje celou oblast, ve které se může nacházet podřízený objekt.
Další informace o metodě GetLayoutData najdete v tématu Výpočet a ukládání dat rozložení do GetLayoutData
Přepsání metody InvalidateLayout
Přepsání Xamarin_Forms _Layout_InvalidateLayout" data-linktype="absolute-path">se vyvolá při přidání nebo odebrání dětí z rozložení nebo při změně hodnoty jedné z vlastností, jak je znázorněno v následujícím příkladu InvalidateLayoutWrapLayout kódu:
protected override void InvalidateLayout()
{
base.InvalidateLayout();
layoutInfoCache.Clear();
}
Přepsání zruší platnost rozložení a zahodí všechny informace o rozložení uložené v mezipaměti.
Poznámka
Chcete-li zastavit volání třídy Xamarin_Forms _Layout_InvalidateLayout" data-linktype="absolute-path">při každém přidání podřízeného objektu do rozložení nebo jeho odebrání, přepište LayoutLayout Xamarin_Forms _Layout_ShouldInvalidateOnChildAdded_ InvalidateLayoutXamarin_Forms _View_" data-linktype="absolute-path">ShouldInvalidateOnChildAdded a Xamarin_Forms InvalidateLayout _Layout_ShouldInvalidateOnChildRemoved_ Xamarin_Forms _View_" data-linktype="absolute-path">ShouldInvalidateOnChildRemovedfalse metody a vrátí . Třída rozložení pak může implementovat vlastní proces, když se přidávají nebo odebraly děti.
Přepsání metody OnChildMeasureInvalidated
Přepsání Xamarin_Forms _Layout_OnChildMeasureInvalidated" data-linktype="absolute-path">se vyvolá při změně velikosti jedné z dětí rozložení a je znázorněno v následujícím příkladu OnChildMeasureInvalidated kódu:
protected override void OnChildMeasureInvalidated()
{
base.OnChildMeasureInvalidated();
layoutInfoCache.Clear();
}
Přepsání zruší platnost podřízeného rozložení a zahodí všechny informace o rozložení uložené v mezipaměti.
Používání objektu WrapLayout
Třídu WrapLayout lze použít umístěním na Page odvozený typ, jak je znázorněno v následujícím příkladu kódu XAML:
<ContentPage ... xmlns:local="clr-namespace:ImageWrapLayout">
<ScrollView Margin="0,20,0,20">
<local:WrapLayout x:Name="wrapLayout" />
</ScrollView>
</ContentPage>
Ekvivalentní kód jazyka C# je zobrazen níže:
public class ImageWrapLayoutPageCS : ContentPage
{
WrapLayout wrapLayout;
public ImageWrapLayoutPageCS()
{
wrapLayout = new WrapLayout();
Content = new ScrollView
{
Margin = new Thickness(0, 20, 0, 20),
Content = wrapLayout
};
}
...
}
Potom je možné podle potřeby přidat do WrapLayout . Následující příklad kódu ukazuje Image přidání prvků do WrapLayout :
protected override async void OnAppearing()
{
base.OnAppearing();
var images = await GetImageListAsync();
if (images != null)
{
foreach (var photo in images.Photos)
{
var image = new Image
{
Source = ImageSource.FromUri(new Uri(photo))
};
wrapLayout.Children.Add(image);
}
}
}
async Task<ImageList> GetImageListAsync()
{
try
{
string requestUri = "https://raw.githubusercontent.com/xamarin/docs-archive/master/Images/stock/small/stock.json";
string result = await _client.GetStringAsync(requestUri);
return JsonConvert.DeserializeObject<ImageList>(result);
}
catch (Exception ex)
{
Debug.WriteLine($"\tERROR: {ex.Message}");
}
return null;
}
Když se zobrazí stránka obsahující , ukázková aplikace asynchronně přistupuje ke vzdálenému souboru JSON obsahujícímu seznam fotek, vytvoří prvek pro každou fotku a přidá WrapLayoutImage ho do WrapLayout . Výsledkem je vzhled zobrazený na následujících snímcích obrazovky:

Na následujících snímcích obrazovky je znázorněna možnost po otočení do WrapLayout orientace na šířku:

obrazovky s ukázkovou aplikací pro Android na šířku Snímek obrazovky s
Počet sloupců v každém řádku závisí na velikosti fotky, šířce obrazovky a počtu pixelů na jednotku nezávislou na zařízení. Prvky asynchronně načítá fotky, >třída proto bude dostávat častá volání do své ImageWrapLayout metody Xamarin_Forms Image _Layout_LayoutChildren_System_Double_System_Double_System_Double_System_Double_" data-linktype="absolutní_cesta">protože každý prvek získá novou velikost na základě LayoutChildrenImage načtené fotky.
Stažení ukázky