Obtenha recursos dimensionados adequadamente para Android e Android Wear

visão global

Vou mostrar como extrair adequadamente um ativo dimensionado (especificamente drawables) para Android ou Android Wear. Atualmente, vejo muitos Bitmap.createScaledBitmapprojetos de exemplo do Google para seus mostradores de relógio. No entanto, isso é extremamente ineficiente e pode retardar as coisas. Se estiver usando isso, então você já carregou a imagem completa na memória e agora está adicionando uma nova versão dela (apenas menor) à sua memória.

Vou mostrar a maneira correta de fazer isso. Este código também é formatado para que você possa colocá-lo em uma Utilclasse e usá-lo em qualquer lugar.

Como isso é feito

O Android especificamente tem uma classe que nos ajuda a construir e trabalhar com imagens, e é chamada BitmapFactory. Usando isso, podemos realmente “decodificar” o arquivo de imagem para obter um pouco de metadados de que precisamos para calcular o novo tamanho. Em seguida, puxe-o nesse tamanho sem ter que carregar totalmente a imagem duas vezes!

Muito legal, certo?

Na prática

Vamos começar com um método padrão que pegará a altura e a largura que você deseja para o recurso e a id do recurso.

// since this is for a static Util Class pass int he resources as well
public static Bitmap pullScaledResourceBitmap(Resources resources, int width, int height, int resourceId) {
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
// set the option to just decode the bounds because we just want
// the dimensions, not the whole image
bitmapOptions
.inJustDecodeBounds = true;
// now decode our resource using these options
BitmapFactory.decodeResource(resources, resourceId, bitmapOptions);
// since we have pulled the dimensions we can set this back to false
// because the next time we decode we want the whole image
bitmapOptions
.inJustDecodeBounds = false;
// look below to see the method to use to update the options to set
// the sample size so we decode at the right size
bitmapOptions
.inSampleSize = calculateInSampleSize(bitmapOptions, width, height);
// now decode the resource again and return it, because it decodes
// as the scaled image!
return BitmapFactory.decodeResource(resources, resourceId, bitmapOptions);
}

public static int calculateInSampleSize(BitmapFactory.Options bitmapOptions, int reqWidth, int reqHeight) {
final int height = bitmapOptions.outHeight;
final int width = bitmapOptions.outWidth;
int inSampleSize = 1;

if (height > reqHeight || width > reqWidth)
{
final int halfHeight = height / 2;
final int halfWidth = width / 2;

while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) {
inSampleSize
*= 2;
}
}

return inSampleSize;
}

Isso é tudo que há para fazer! De uma chance.