Imagens em Xamarin.Forms
As imagens podem ser compartilhadas entre plataformas com Xamarin.Formso , podem ser carregadas especificamente para cada plataforma ou podem ser baixadas para exibição.
As imagens são uma parte crucial da navegação, usabilidade e identidade visual do aplicativo. Xamarin.Forms Os aplicativos precisam ser capazes de compartilhar imagens em todas as plataformas, mas também exibir imagens diferentes em cada plataforma.
Imagens específicas da plataforma também são necessárias para ícones e telas iniciais; eles precisam ser configurados por plataforma.
Exibir imagens
Xamarin.Forms usa a Image
exibição para exibir imagens em uma página. Tem várias propriedades importantes:
Source
- UmaImageSource
instância, File, Uri ou Resource, que define a imagem a ser exibida.Aspect
- Como dimensionar a imagem dentro dos limites em que ela está sendo exibida (seja para esticar, cortar ou letterbox).
ImageSource
As instâncias podem ser obtidas usando métodos estáticos para cada tipo de fonte de imagem:
FromFile
- Requer um nome de arquivo ou caminho de arquivo que possa ser resolvido em cada plataforma.FromUri
- Requer um objeto Uri, por exemplo.new Uri("http://server.com/image.jpg")
.FromResource
- Requer um identificador de recurso para um arquivo de imagem inserido no aplicativo ou no projeto de biblioteca do .NET Standard, com um Build Action:EmbeddedResource.FromStream
- Requer um fluxo que forneça dados de imagem.
A Aspect
propriedade determina como a imagem será dimensionada para caber na área de exibição:
Fill
- Estica a imagem para preencher completa e exatamente a área de exibição. Isso pode fazer com que a imagem fique distorcida.AspectFill
- Recorta a imagem para que ela preencha a área de exibição, preservando o aspecto (ou seja, sem distorção).AspectFit
- Caixas de correio a imagem (se necessário) para que toda a imagem caiba na área de exibição, com espaço em branco adicionado à parte superior/inferior ou laterais, dependendo se a imagem é larga ou alta.
As imagens podem ser carregadas de um arquivo local, de um recurso incorporado, baixadas ou carregadas de um fluxo. Além disso, os Image
ícones de fonte podem ser exibidos pela exibição especificando os dados do ícone de fonte em um FontImageSource
objeto. Para obter mais informações, consulte Exibir ícones de fonte no guia Fontes.
Imagens locais
Os arquivos de imagem podem ser adicionados a cada projeto de aplicativo e referenciados a partir do Xamarin.Forms código compartilhado. Esse método de distribuição de imagens é necessário quando as imagens são específicas da plataforma, como ao usar resoluções diferentes em diferentes plataformas ou designs ligeiramente diferentes.
Para usar uma única imagem em todos os aplicativos, o mesmo nome de arquivo deve ser usado em todas as plataformas e deve ser um nome de recurso válido do Android (ou seja, apenas letras minúsculas, numerais, sublinhado e ponto são permitidos).
- iOS – a maneira preferencial de gerenciar e dar suporte a imagens desde o iOS 9 é usar Conjuntos de Imagens do Catálogo de Ativos, que devem conter todas as versões de uma imagem necessárias para dar suporte a vários dispositivos e fatores de escala para um aplicativo. Para obter mais informações, consulte Adicionar imagens a um conjunto de imagens do catálogo de ativos.
- Android - Coloque imagens no diretório Resources/drawable com Build Action: AndroidResource. Versões de alto e baixo DPI de uma imagem também podem ser fornecidas (em subdiretórios Resources nomeados adequadamente, como drawable-ldpi, drawable-hdpi e drawable-xhdpi).
- Plataforma Universal do Windows (UWP) – por padrão, as imagens devem ser colocadas no diretório raiz do aplicativo com Ação de Build: Conteúdo. Como alternativa, as imagens podem ser colocadas em um diretório diferente, que é especificado com um específico da plataforma. Para obter mais informações, consulte Diretório de imagem padrão no Windows.
Importante
Antes do iOS 9, as imagens normalmente eram colocadas na pasta Resources com Build Action: BundleResource. No entanto, esse método de trabalhar com imagens em um aplicativo iOS foi preterido pela Apple. Para obter mais informações, consulte Tamanhos de imagem e nomes de arquivo.
A adesão a essas regras de nomenclatura e posicionamento de arquivos permite que o seguinte XAML carregue e exiba a imagem em todas as plataformas:
<Image Source="waterfront.jpg" />
O código C# equivalente é o seguinte:
var image = new Image { Source = "waterfront.jpg" };
As capturas de tela a seguir mostram o resultado da exibição de uma imagem local em cada plataforma:
Para obter mais flexibilidade, a Device.RuntimePlatform
propriedade pode ser usada para selecionar um arquivo de imagem ou caminho diferente para algumas ou todas as plataformas, conforme mostrado neste exemplo de código:
image.Source = Device.RuntimePlatform == Device.Android
? ImageSource.FromFile("waterfront.jpg")
: ImageSource.FromFile("Images/waterfront.jpg");
Importante
Para usar o mesmo nome de arquivo de imagem em todas as plataformas, o nome deve ser válido em todas as plataformas. Os drawables do Android têm restrições de nomenclatura – apenas letras minúsculas, números, sublinhado e ponto são permitidos – e, para compatibilidade entre plataformas, isso também deve ser seguido em todas as outras plataformas. O nome de arquivo de exemplo waterfront.png segue as regras, mas exemplos de nomes de arquivo inválidos incluem "water front.png", "WaterFront.png", "water-front.png" e "wåterfront.png".
Resoluções nativas (retina e alto DPI)
iOS, Android e UWP incluem suporte para diferentes resoluções de imagem, em que o sistema operacional escolhe a imagem apropriada em tempo de execução com base nos recursos do dispositivo. Xamarin.Forms usa as APIs das plataformas nativas para carregar imagens locais, portanto, suporta automaticamente resoluções alternativas se os arquivos estiverem corretamente nomeados e localizados no projeto.
A maneira preferida de gerenciar imagens desde o iOS 9 é arrastar imagens para cada resolução necessária para o conjunto de imagens do catálogo de ativos apropriado. Para obter mais informações, consulte Adicionar imagens a um conjunto de imagens do catálogo de ativos.
Antes do iOS 9, as versões retina da imagem podiam ser colocadas na pasta Recursos - duas e três vezes a resolução com um @2x ou @3x sufixos no nome do arquivo antes da extensão do arquivo (por exemplo, myimage@2x.png). No entanto, esse método de trabalhar com imagens em um aplicativo iOS foi preterido pela Apple. Para obter mais informações, consulte Tamanhos de imagem e nomes de arquivo.
As imagens de resolução alternativa do Android devem ser colocadas em diretórios com nomes especiais no projeto Android, conforme mostrado na captura de tela a seguir:
Os nomes de arquivo de imagem UWP podem ser sufixados antes .scale-xxx
da extensão do arquivo, em que xxx
é a porcentagem de dimensionamento aplicada ao ativo, por exemplo , myimage.scale-200.png. As imagens podem ser referenciadas em código ou XAML sem o modificador de escala, por exemplo, apenas myimage.png. A plataforma selecionará a escala de ativos apropriada mais próxima com base no DPI atual da tela.
Controles adicionais que exibem imagens
Alguns controles têm propriedades que exibem uma imagem, como:
Button
tem umaImageSource
propriedade que pode ser definida como uma imagem bitmap a ser exibida noButton
. Para obter mais informações, consulte Usando bitmaps com botões.ImageButton
tem umaSource
propriedade que pode ser definida como a imagem a ser exibida noImageButton
. Para obter mais informações, consulte Configurando a origem da imagem.ToolbarItem
tem umaIconImageSource
propriedade que pode ser definida como uma imagem carregada de um arquivo, recurso inserido, URI ou fluxo.ImageCell
tem umaImageSource
propriedade que pode ser definida como uma imagem recuperada de um arquivo, recurso inserido, URI ou fluxo.Page
. Qualquer tipo de página derivado dePage
hasIconImageSource
eBackgroundImageSource
properties, que pode ser atribuído a um arquivo, recurso inserido, URI ou fluxo. Em determinadas circunstâncias, como quando aNavigationPage
está exibindo umContentPage
, o ícone será exibido se suportado pela plataforma.Importante
No iOS, a
Page.IconImageSource
propriedade não pode ser preenchida a partir de uma imagem em um conjunto de imagens do catálogo de ativos. Em vez disso, carregue imagens de ícone para aPage.IconImageSource
propriedade de um arquivo, recurso inserido, URI ou fluxo.
Imagens incorporadas
As imagens incorporadas também são enviadas com um aplicativo (como imagens locais), mas em vez de ter uma cópia da imagem na estrutura de arquivos de cada aplicativo, o arquivo de imagem é inserido no assembly como um recurso. Esse método de distribuição de imagens é recomendado quando imagens idênticas são usadas em cada plataforma e é particularmente adequado para a criação de componentes, pois a imagem é empacotada com o código.
Para incorporar uma imagem em um projeto, clique com o botão direito do mouse para adicionar novos itens e selecione a(s) imagem(ns) que deseja adicionar. Por padrão, a imagem terá Ação de Build: Nenhum; isso precisa ser definido como Ação de Build: EmbeddedResource.
A Ação de Construção pode ser visualizada e alterada na janela Propriedades de um arquivo.
Neste exemplo, a ID do recurso é WorkingWithImages.beach.jpg. O IDE gerou esse padrão concatenando o Namespace padrão para este projeto com o nome do arquivo, usando um ponto (.) entre cada valor.
Se você colocar imagens incorporadas em pastas dentro do projeto, os nomes das pastas também serão separados por pontos (.) na ID do recurso. Mover a imagem beach.jpg para uma pasta chamada MyImages resultaria em uma ID de recurso de WorkingWithImages.MyImages.beach.jpg
O código para carregar uma imagem inserida simplesmente passa a ID do recurso para o método, ImageSource.FromResource
conforme mostrado abaixo:
Image embeddedImage = new Image
{
Source = ImageSource.FromResource("WorkingWithImages.beach.jpg", typeof(MyClass).GetTypeInfo().Assembly)
};
Observação
Para dar suporte à exibição de imagens inseridas no modo de versão na Plataforma Universal do Windows, é necessário usar a sobrecarga de que especifica o assembly de ImageSource.FromResource
origem no qual pesquisar a imagem.
Atualmente, não há conversão implícita para identificadores de recursos. Em vez disso, você deve usar ImageSource.FromResource
ou new ResourceImageSource()
carregar imagens incorporadas.
As capturas de tela a seguir mostram o resultado da exibição de uma imagem incorporada em cada plataforma:
XAML
Como não há nenhum conversor de tipo interno de string
para ResourceImageSource
, esses tipos de imagens não podem ser carregados nativamente por XAML. Em vez disso, uma extensão de marcação XAML personalizada simples pode ser gravada para carregar imagens usando uma ID de recurso especificada em XAML:
[ContentProperty (nameof(Source))]
public class ImageResourceExtension : IMarkupExtension
{
public string Source { get; set; }
public object ProvideValue (IServiceProvider serviceProvider)
{
if (Source == null)
{
return null;
}
// Do your translation lookup here, using whatever method you require
var imageSource = ImageSource.FromResource(Source, typeof(ImageResourceExtension).GetTypeInfo().Assembly);
return imageSource;
}
}
Observação
Para dar suporte à exibição de imagens inseridas no modo de versão na Plataforma Universal do Windows, é necessário usar a sobrecarga de que especifica o assembly de ImageSource.FromResource
origem no qual pesquisar a imagem.
Para usar essa extensão, adicione um personalizado xmlns
ao XAML, usando o namespace correto e os valores de assembly para o projeto. A fonte da imagem pode então ser definida usando esta sintaxe: {local:ImageResource WorkingWithImages.beach.jpg}
. Um exemplo completo de XAML é mostrado abaixo:
<?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:local="clr-namespace:WorkingWithImages;assembly=WorkingWithImages"
x:Class="WorkingWithImages.EmbeddedImagesXaml">
<StackLayout VerticalOptions="Center" HorizontalOptions="Center">
<!-- use a custom Markup Extension -->
<Image Source="{local:ImageResource WorkingWithImages.beach.jpg}" />
</StackLayout>
</ContentPage>
Solucionar problemas de imagens incorporadas
Depurar o código
Como às vezes é difícil entender por que um determinado recurso de imagem não está sendo carregado, o código de depuração a seguir pode ser adicionado temporariamente a um aplicativo para ajudar a confirmar se os recursos estão configurados corretamente. Ele produzirá todos os recursos conhecidos inseridos no assembly fornecido para o Console para ajudar a depurar problemas de carregamento de recursos.
using System.Reflection;
// ...
// NOTE: use for debugging, not in released app code!
var assembly = typeof(MyClass).GetTypeInfo().Assembly;
foreach (var res in assembly.GetManifestResourceNames())
{
System.Diagnostics.Debug.WriteLine("found resource: " + res);
}
Imagens incorporadas em outros projetos
Por padrão, o ImageSource.FromResource
método procura apenas imagens no mesmo assembly que o código que chama o ImageSource.FromResource
método. Usando o código de depuração acima, você pode determinar quais assemblies contêm um recurso específico alterando a typeof()
instrução para um Type
conhecido em cada assembly.
No entanto, o assembly de origem que está sendo pesquisado por uma imagem inserida pode ser especificado como um argumento para o ImageSource.FromResource
método:
var imageSource = ImageSource.FromResource("filename.png",
typeof(MyClass).GetTypeInfo().Assembly);
Baixar imagens
As imagens podem ser baixadas automaticamente para exibição, conforme mostrado no seguinte XAML:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WorkingWithImages.DownloadImagesXaml">
<StackLayout VerticalOptions="Center" HorizontalOptions="Center">
<Label Text="Image UriSource Xaml" />
<Image Source="https://aka.ms/campus.jpg" />
<Label Text="campus.jpg gets downloaded from microsoft.com" />
</StackLayout>
</ContentPage>
O código C# equivalente é o seguinte:
var webImage = new Image {
Source = ImageSource.FromUri(
new Uri("https://aka.ms/campus.jpg")
) };
O ImageSource.FromUri
método requer um Uri
objeto e retorna um novo UriImageSource
que lê a partir do Uri
.
Há também uma conversão implícita para cadeias de caracteres de URI, portanto, o exemplo a seguir também funcionará:
webImage.Source = "https://aka.ms/campus.jpg";
As capturas de tela a seguir mostram o resultado da exibição de uma imagem remota em cada plataforma:
Cache de imagem baixado
A UriImageSource
também suporta cache de imagens baixadas, configurado por meio das seguintes propriedades:
CachingEnabled
- Se o cache está habilitado (true
por padrão).CacheValidity
- UmTimeSpan
que define por quanto tempo a imagem ficará armazenada localmente.
O cache é ativado por padrão e armazenará a imagem localmente por 24 horas. Para desabilitar o cache de uma imagem específica, instancie a origem da imagem da seguinte maneira:
image.Source = new UriImageSource { CachingEnabled = false, Uri = new Uri("https://server.com/image") };
Para definir um período de cache específico (por exemplo, 5 dias), instancie a origem da imagem da seguinte maneira:
webImage.Source = new UriImageSource
{
Uri = new Uri("https://aka.ms/campus.jpg"),
CachingEnabled = true,
CacheValidity = new TimeSpan(5,0,0,0)
};
O cache interno facilita muito o suporte a cenários como listas de rolagem de imagens, em que você pode definir (ou associar) uma imagem em cada célula e permitir que o cache interno se encarregue de recarregar a imagem quando a célula for rolada de volta à exibição.
GIFs animados
Xamarin.Forms inclui suporte para exibir GIFs pequenos e animados. Isso é feito definindo a Image.Source
propriedade como um arquivo GIF animado:
<Image Source="demo.gif" />
Importante
Embora o suporte Xamarin.Forms a GIFs animados inclua a capacidade de baixar arquivos, ele não oferece suporte a cache ou streaming de GIFs animados.
Por padrão, quando um GIF animado é carregado, ele não será reproduzido. Isso ocorre porque a propriedade, que controla IsAnimationPlaying
se um GIF animado está sendo reproduzido ou interrompido, tem um valor padrão de false
. Essa propriedade, do tipo bool
, é apoiada por um BindableProperty
objeto, o que significa que ela pode ser o destino de uma associação de dados e estilizada.
Portanto, quando um GIF animado é carregado, ele não será reproduzido até que a IsAnimationPlaying
propriedade seja definida como true
. A reprodução pode ser interrompida definindo a IsAnimationPlaying
propriedade como false
. Observe que essa propriedade não tem efeito ao exibir uma fonte de imagem não GIF.
Observação
No Android, o suporte a GIFs animados exige que seu aplicativo esteja usando renderizadores rápidos e não funcionará se você tiver optado por usar os renderizadores legados. Na UWP, o suporte a GIF animado requer uma versão mínima da Atualização de Aniversário do Windows 10 (versão 1607).
Ícones e telas iniciais
Embora não estejam relacionados à visualização, os Image
ícones de aplicativos e as telas iniciais também são um uso importante de imagens em Xamarin.Forms projetos.
A configuração de ícones e telas iniciais para Xamarin.Forms aplicativos é feita em cada um dos projetos de aplicativos. Isso significa gerar imagens dimensionadas corretamente para iOS, Android e UWP. Essas imagens devem ser nomeadas e localizadas de acordo com os requisitos de cada plataforma.
Ícones
Consulte o iOS Trabalhando com imagens, Iconografia do Google e Diretrizes UWP para ativos de bloco e ícone para obter mais informações sobre como criar esses recursos de aplicativo.
Além disso, os Image
ícones de fonte podem ser exibidos pela exibição especificando os dados do ícone de fonte em um FontImageSource
objeto. Para obter mais informações, consulte Exibir ícones de fonte no guia Fontes.
Telas iniciais
Somente aplicativos iOS e UWP exigem uma tela inicial (também chamada de tela de inicialização ou imagem padrão).
Consulte a documentação do iOS Trabalhando com imagens e telas iniciais no Centro de Desenvolvimento do Windows.