Zusammenfassung von Kapitel 13. Bitmaps
Hinweis
Dieses Buch wurde im Frühjahr 2016 veröffentlicht und seitdem nicht aktualisiert. Wenngleich ein großer Teil des Buchs weiterhin relevante Informationen liefert, sind einige Abschnitte veraltet, und einige Themen sind nicht mehr korrekt oder vollständig.
Das Xamarin.FormsImage
Element zeigt eine Bitmap an. Alle Xamarin.Forms-Plattformen unterstützen die Dateiformate JPEG, PNG, GIF und BMP.
Bitmaps in Xamarin.Forms stammen aus vier Quellen:
- Aus dem Internet, angegeben durch eine URL.
- Eingebettet als Ressource in der freigegebenen Bibliothek.
- Eingebettet als Ressource in den Plattformanwendungsprojekten.
- Von jedem Ort, auf den über ein
Stream
-Objekt von .NET verwiesen werden kann, einschließlichMemoryStream
Bitmapressourcen in der freigegebenen Bibliothek sind plattformunabhängig, während Bitmapressourcen in den Plattformprojekten plattformspezifisch sind.
Hinweis
Im Text dieses Buchs wird auf portable Klassenbibliotheken verwiesen, die durch .NET Standard-Bibliotheken ersetzt wurden. Der gesamte Beispielcode innerhalb des Buchs wurde aktualisiert und verwendet jetzt die .NET Standard-Bibliotheken.
Die Angabe der Bitmap erfolgt durch Festlegen der Source
-Eigenschaft von Image
auf ein Objekt vom Typ ImageSource
, eine abstrakte Klasse mit drei Ableitungen:
UriImageSource
für den Zugriff auf eine Bitmap über das Internet, basierend auf einem auf seineUri
-Eigenschaft festgelegtesUri
-Objekt.FileImageSource
für den Zugriff auf eine in einem Plattformanwendungsprojekt gespeicherte Bitmap, basierend auf einem auf seineFile
-Eigenschaft festgelegten Ordner- und Dateipfad.StreamImageSource
zum Laden einer Bitmap mithilfe einesStream
-Objekts von .NET, das durch Zurückgeben einesStream
von einerFunc
, die auf seineStream
-Eigenschaft festgelegt wurde, angegeben wird.
Alternativ (und etwas gängiger) können Sie die folgenden statischen Methoden der ImageSource
-Klasse verwenden, die alle ImageSource
-Objekte zurückgeben:
ImageSource.FromUri
für den Zugriff auf eine Bitmap über das Internet, basierend auf einemUri
-Objekt.ImageSource.FromResource
für den Zugriff auf eine Bitmap, die als eingebettete Ressource in der Anwendungs-PCL gespeichert ist;ImageSource.FromResource
oderImageSource.FromResource
für den Zugriff auf eine Bitmap in einer anderen Quellassembly.ImageSource.FromFile
für den Zugriff auf eine Bitmap aus einem Plattformanwendungsprojekt.ImageSource.FromStream
zum Laden einer Bitmap, basierend auf einemStream
-Objekt.
Es gibt keine Klassenentsprechung für die Image.FromResource
-Methoden. Die UriImageSource
-Klasse ist nützlich, wenn Sie das Zwischenspeichern kontrollieren müssen. Die FileImageSource
-Klasse ist nützlich in XAML. StreamImageSource
ist nützlich für das asynchrone Laden von Stream
-Objekten, während ImageSource.FromStream
synchron ist.
Plattformunabhängige Bitmaps
Das WebBitmapCode-Projekt lädt eine Bitmap über das Internet mithilfe von ImageSource.FromUri
. Das Image
-Element wird auf die Content
-Eigenschaft von ContentPage
festgelegt, sodass es auf die Größe der Seite eingeschränkt ist. Unabhängig von der Größe der Bitmap wird ein eingeschränktes Image
-Element auf die Größe seines Containers gestreckt, und die Bitmap wird in ihrer maximalen Größe innerhalb des Image
-Elements angezeigt, wobei das Seitenverhältnis der Bitmap beibehalten wird. Bereiche des Image
, die über die Bitmap hinausgehen, können mit BackgroundColor
eingefärbt werden.
Das WebBitmapXaml-Beispiel ist ähnlich, legt aber die Source
-Eigenschaft einfach auf die URL fest. Die Konvertierung wird von der ImageSourceConverter
-Klasse durchgeführt.
Anpassung und Füllung
Sie können kontrollieren, wie die Bitmap gestreckt wird, indem Sie die Aspect
-Eigenschaft von Image
auf einen der folgenden Member der Aspect
-Enumeration festlegen:
AspectFit
: behält das Seitenverhältnis bei (Standard).Fill
: füllt den Bereich aus, ignoriert das Seitenverhältnis.AspectFill
: füllt den Bereich aus, aber behält das Seitenverhältnis bei, was durch Zuschneiden eines Teils der Bitmap erreicht wird.
Eingebettete Ressourcen
Sie können einer PCL oder einem Ordner in der PCL eine Bitmapdatei hinzufügen. Statten Sie sie mit dem Buildvorgang EmbeddedResource aus. Das ResourceBitmapCode-Beispiel veranschaulicht, wie Sie ImageSource.FromResource
zum Laden der Datei verwenden. Der an die Methode übergebene Ressourcenname besteht aus dem Assemblynamen, gefolgt von einem Punkt, gefolgt vom optionalen Ordnernamen und einem Punkt, gefolgt vom Dateinamen.
Das Programm legt die Eigenschaften VerticalOptions
und HorizontalOptions
von Image
auf LayoutOptions.Center
fest, wodurch das Image
-Element uneingeschränkt wird. Das Image
und die Bitmap haben dieselbe Größe:
- Unter iOS und Android hat
Image
die Pixelgröße der Bitmap. Es findet eine 1:1-Zuordnung zwischen Bitmappixeln und Bildschirmpixeln statt. - Bei der universellen Windows-Plattform hat
Image
die Pixelgröße der Bitmap in geräteunabhängigen Einheiten. Auf den meisten Geräten belegt jedes Bitmappixel mehrere Bildschirmpixel.
Im StackedBitmap-Beispiel wird ein Image
in ein vertikales StackLayout
in XAML gebracht. Eine Benannte ImageResourceExtension
Markuperweiterung hilft, auf die eingebettete Ressource in XAML zu verweisen. Diese Klasse lädt nur Ressourcen aus der Assembly, in der sie sich befindet, sodass sie nicht in einer Bibliothek abgelegt werden kann.
Weitere Informationen zur Größenanpassung
Häufig ist es wünschenswert, die Größe von Bitmaps konsistent über alle Plattformen hinweg anzupassen.
Durch Experimentieren mit StackedBitmap können Sie eine WidthRequest
für das Image
-Element in einem vertikalen StackLayout
festlegen, um die Größe auf allen Plattformen konsistent zu halten, aber verringern können Sie die Größe nur mithilfe dieser Methode.
Sie können außerdem die HeightRequest
festlegen, um die Bildgrößen auf den Plattformen konsistent zu halten, aber die eingeschränkte Breite der Bitmap schränkt die Vielseitigkeit dieser Methode ein. Bei einem Bild in einem vertikalen StackLayout
sollte HeightRequest
vermieden werden.
Der beste Ansatz besteht darin, mit einer Bitmap zu beginnen, die in geräteunabhängigen Einheiten breiter als das Telefon ist, und WidthRequest
auf die gewünschte Breite in geräteunabhängigen Einheiten festzulegen. Dies wird im DeviceIndBitmapSize-Beispiel demonstriert.
Das Beispiel MadTeaParty zeigt Kapitel 7 von Alice im Wunderland von Lewis Carroll mit den Originalillustrationen von John Tenniel:
Durchsuchen und Warten
Das ImageBrowser-Beispiel gestattet dem Benutzer das Durchsuchen von Archivbildern, die auf der Xamarin-Website gespeichert sind. Es verwendet die WebRequest
-Klasse von .NET zum Herunterladen einer JSON-Datei mit der Liste der Bitmaps.
Hinweis
Für Xamarin.Forms-Programme sollte HttpClient
anstelle von WebRequest
für den Zugriff auf Dateien über das Internet verwendet werden.
Das Programm verwendet einen ActivityIndicator
, um anzuzeigen, das etwas durchgeführt wird. Bei jedem Laden einer Bitmap hat die schreibgeschützte Eigenschaft IsLoading
von Image
den Wert true
. Die IsLoading
-Eigenschaft wird von einer bindbaren Eigenschaft unterstützt, sodass ein PropertyChanged
-Ereignis ausgelöst wird, wenn sich diese Eigenschaft ändert. Das Programm fügt einen Handler an dieses Ereignis an und verwendet die aktuelle Einstellung von IsLoaded
, um die IsRunning
-Eigenschaft des ActivityIndicator
festzulegen.
Streaming von Bitmaps
Die ImageSource.FromStream
-Methode erstellt auf Grundlage eines Stream
von .NET eine ImageSource
. An die Methode muss ein Func
-Objekt übergeben werden, das ein Stream
-Objekt zurückgibt.
Zugreifen auf die Streams
Das BitmapStreams-Beispiel veranschaulicht, wie Sie die ImaageSource.FromStream
-Methode verwenden, um eine Bitmap zu laden, die als eingebettete Ressource gespeichert ist, und um eine Bitmap über das Internet zu laden.
Generieren von Bitmaps zur Laufzeit
Alle Xamarin.Forms-Plattformen unterstützen das unkomprimierte BMP-Dateiformat, das sich in Code einfach erstellen und dann in MemoryStream
speichern lässt. Diese Methode ermöglicht das algorithmische Erstellen von Bitmaps zur Laufzeit, wie in der BmpMaker
-Klasse in der Xamrin.FormsBook.Toolkit-Bibliothek implementiert.
Das „Do-it-yourself“-Beispiel DiyGradientBitmap veranschaulicht die Verwendung von BmpMaker
zum Erstellen einer Bitmap mit einem Farbverlaufsbild.
Plattformspezifische Bitmaps
Alle Xamarin.Forms-Plattformen erlauben das Speichern von Bitmaps in den Plattformanwendungsassemblys. Wenn sie von einer Xamarin.Forms-Anwendung abgerufen werden, sind diese Plattformbitmaps vom Typ FileImageSource
. Sie verwenden sie für Folgendes:
- die
Icon
-Eigenschaft vonMenuItem
- die
Icon
-Eigenschaft vonToolbarItem
- die
Image
-Eigenschaft vonButton
Die Plattformassemblys enthalten bereits Bitmaps für Symbole und Begrüßungsbildschirme:
- im iOS-Projekt im Ordner Resources (Ressourcen).
- im Android-Projekt in den Unterordnern des Ordners Resources (Ressourcen).
- in den Windows-Projekten im Ordner Assets (Ressourcen; obgleich die Windows-Plattformen Bitmaps nicht nur auf diesen Ordner beschränken).
Das PlatformBitmaps-Beispiel verwendet Code zum Anzeigen eines Symbols aus den Plattformanwendungsprojekten.
Bitmapauflösungen
Alle Plattformen gestatten das Speichern mehrerer Versionen von Bitmapbildern für unterschiedliche Geräteauflösungen. Zur Laufzeit wird die richtige Version geladen, basierend auf der Geräteauflösung des Bildschirms.
Unter iOS werden diese Bitmaps durch ein Suffix am Dateinamen unterschieden:
- Kein Suffix bei 160-DPI-Geräten (1 Pixel pro geräteunabhängige Einheit)
- Suffix "@2x" für 320 DPI-Geräte (2 Pixel bis diU)
- Suffix "@3x" für 480 DPI-Geräte (3 Pixel bis diU)
Eine für die Anzeige als Quadrat mit Seitenlänge 2,54 cm gedachte Bitmap gäbe es in drei Versionen:
- „MyImage.jpg“ mit 160 Pixel im Quadrat
- „MyImage@2x.jpg“ mit 320 Pixel im Quadrat
- „MyImage@3x.jpg“ mit 480 Pixel im Quadrat
Das Programm würde auf diese Bitmap als „MyImage.jpg“ verweisen, doch die richtige Version wird zur Laufzeit abgerufen, basierend auf der Auflösung des Bildschirms. Wenn die Bitmap uneingeschränkt ist, wird sie immer mit 160 geräteunabhängigen Einheiten gerendert.
Unter Android werden Bitmaps in verschiedenen Unterordnern des Ordners Ressourcen gespeichert:
- „drawable-ldpi“ (niedrige DPI) bei 120-DPI-Geräten (0,75 Pixel pro geräteunabhängige Einheit)
- „drawable-mdpi“ (mittel) bei 160-DPI-Geräten (1 Pixel pro geräteunabhängige Einheit)
- „drawable-hdpi“ (hoch) bei 240-DPI-Geräten (1,5 Pixel pro geräteunabhängige Einheit)
- „drawable-xhdpi“ (sehr hoch) bei 320-DPI-Geräten (2 Pixel pro geräteunabhängige Einheit)
- „drawable-xxhdpi“ (besonders hoch) bei 480-DPI-Geräten (3 Pixel pro geräteunabhängige Einheit)
- „drawable-xxxhdpi“ (extrem hoch) bei 640-DPI-Geräten (4 Pixel pro geräteunabhängige Einheit)
Bei einer für das Rendern als Quadrat mit Seitenlänge 2,54 cm gedachten Bitmap besitzen die verschiedenen Versionen der Bitmap denselben Namen, aber eine andere Größe, und werden in diesen Ordnern gespeichert:
- „drawable-ldpi/MyImage.jpg“ mit 120 Pixel im Quadrat
- „drawable-mdpi/MyImage.jpg“ mit 160 Pixel im Quadrat
- „drawable-hdpi/MyImage.jpg“ mit 240 Pixel im Quadrat
- „drawable-xhdpi/MyImage.jpg“ mit 320 Pixel im Quadrat
- „drawable-xxhdpi/MyImage.jpg“ mit 480 Pixel im Quadrat
- „drawable-xxxhdpi/MyImage.jpg“ mit 640 Pixel im Quadrat
Die Bitmap wird immer mit 160 geräteunabhängigen Einheiten gerendert. (Die standardmäßige Xamarin.Forms-Projektmappenvorlage umfasst nur die Ordner „hdpi“, „xhdpi“ und „xxhdpi“.)
Das UWP-Projekt unterstützt ein Benennungsschema für Bitmaps, das aus einem Skalierungsfaktor in Pixel pro geräteunabhängiger Einheit als Prozentsatz besteht, z. B.:
- „MyImage.scale-200.jpg“ mit 320 Pixel im Quadrat
Nur manche Prozentsätze sind gültig. Die Beispielprogramme für dieses Buch enthalten nur Bilder mit scale-200-Suffixen, aber aktuelle Xamarin.Forms-Projektmappenvorlagen enthalten scale-100, scale-125, scale-150 und scale-400.
Beim Hinzufügen von Bitmaps zu den Plattformprojekten sollte der Erstellungsvorgang der folgende sein:
- iOS: BundleResource
- Android: AndroidResource
- UWP: Inhalt
Im ImageTap-Beispiel werden zwei schaltflächenähnliche Objekte erstellt, die aus Image
-Elementen mit installiertem TapGestureRecognizer
bestehen. Die Objekte sollen die Größe eines Quadrats mit Seitenlänge 2,54 cm haben. Die Source
-Eigenschaft von Image
wird mithilfe der Objekte OnPlatform
und On
so festgelegt, dass sie potenziell auf unterschiedliche Dateinamen auf den Plattformen verweist. Die Bitmapbilder enthalten Nummern, die ihre Pixelgröße anzeigen, sodass Sie erkennen können, welche Bitmapgröße abgerufen und gerendert wird.
Symbolleisten und ihre Symbole
Einer der primären Verwendungszwecke plattformspezifischer Bitmaps ist die Xamarin.Forms-Symbolleiste, die erstellt wird, indem ToolbarItem
-Objekte der von Page
definierten ToolbarItems
-Sammlung hinzugefügt werden. ToobarItem
wird von MenuItem
abgeleitet, von dem es einige Eigenschaften erbt.
Die wichtigsten ToolbarItem
-Eigenschaften sind:
Text
für Text, der abhängig von Plattform undOrder
möglicherweise angezeigt wird.Icon
vom TypFileImageSource
für das Bild, das abhängig von Plattform undOrder
möglicherweise angezeigt wird.Order
vom TypToolbarItemOrder
, eine Enumeration mit drei Zahlen,Default
,Primary
undSecondary
.
Die Anzahl der Primary
-Elemente sollte auf drei oder vier beschränkt werden. Sie sollten eine Text
-Einstellung für alle Elemente einschließen. Bei den meisten Plattformen erfordern nur die Primary
-Elemente ein Icon
, doch Windows 8.1 erfordert für alle Elemente ein Icon
. Die Symbole sollten 32 geräteunabhängige Einheiten im Quadrat sein. Der FileImageSource
-Typ gibt an, dass sie plattformspezifisch sind.
Das ToolbarItem
löst ein Clicked
-Ereignis aus, wenn darauf getippt wird, ganz ähnlich wie eine Button
. ToolbarItem
unterstützt auch die Eigenschaften Command
und CommandParameter
, die häufig in Verbindung mit MVVM verwendet werden. (Siehe Kapitel 18, „MVVM“.)
Sowohl iOS als auch Android erfordern, dass eine Seite, auf der eine Symbolleiste angezeigt wird, eine NavigationPage
ist oder eine Seite, auf die man von einer NavigationPage
weitergeleitet wurde. Das ToolbarDemo-Programm legt die MainPage
-Eigenschaft seiner App
-Klasse auf den NavigationPage
-Konstruktor mit einem ContentPage
-Argument fest und veranschaulicht den Konstruktions- und Ereignishandler einer Symbolleiste.
Schaltflächenbilder
Sie können auch plattformspezifische Bitmaps verwenden, um die Image
-Eigenschaft von Button
auf eine Bitmap mit 32 geräteunabhängigen Einheiten im Quadrat festzulegen, wie im ButtonImage-Beispiel veranschaulicht.
Hinweis
Die Verwendung von Bildern auf Schaltflächen wurde verbessert. Siehe Verwenden von Bitmaps mit Schaltflächen.