segunda-feira, 4 de abril de 2016

Carregando imagens de outras fontes com o Picasso

Olá pessoal,

As bibliotecas de carregamento de imagens são utilizadas em praticamente todos os projetos Android. Elas facilitam o carregamento de imagens a partir de diversas fontes como: web, sistema de arquivos e até de banco de dados. Possuem recursos de redimensionamento, crop, placeholder, animação, etc. As mais famosas desse segmento são: Picasso, Glide e Universal Image Loader (UIL). Todas são ótimas, já resolvi uns problemas com uma, outros problemas com outra e por aí vai.
No projeto que estou atualmente estou usando o Picasso, e estava precisando carregar imagens de um local não suportado nativamente por ele: o arquivo de expansão de APK.
Graças ao grande mestre Jake Wharton, podemos implementar isso de uma forma muito fácil. Basta criar uma subclasse de RequestHandler.
import com.squareup.picasso.Request;
import com.squareup.picasso.RequestHandler;

public class MeuRequestHandler extends RequestHandler {

    public MeuRequestHandler() {
    }

    @Override
    public boolean canHandleRequest(Request data) {
        // Retorne true se essa classe pode tratar a leitura da imagem
        return data != null
                && data.uri != null
                && data.uri.getScheme() != null
                && data.uri.getScheme().startsWith("ngvl");
    }

    @Override
    public Result load(Request request, int networkPolicy) 
            throws IOException {
        Bitmap imagem = metodoQueCarregaSeuBitmap(request.uri);
        Result result = new Result(imagem, Picasso.LoadedFrom.DISK);
        return result;
    }
}
Essa classe possui apenas dois métodos:
  • canHandleRequest(Request) define se essa classe é capaz de carregar uma determinada imagem. Nesse exemplo, estou usando o parâmetro Request para checar se o endereço (definido por uma Uri) começa com "ngvl". 
  • Já o método load(Request, int) carrega a imagem em si e a retorna por meio de um objeto Result, que recebe o Bitmap da imagem e de onde ela foi carregada (memória, disco ou rede).
Criado o handler, basta adicioná-lo a uma instância do Picasso.
Picasso = mPicassoInstance = 
    new Picasso.Builder(mContext.getApplicationContext())
        .addRequestHandler(new MeuRequestHandler())
        .build();
Com isso, você está adicionando uma nova fonte de imagens à sua instância do Picasso, ou seja, você pode usar todos os schemas já suportados pelo Picasso (http, file, content, ...) e esse que acabamos de criar.
Agora, se invocarmos o código a seguir, o nosso handler tratará essa requisição.
mPicassoInstance
        .load("ngvl://minhaimagem/logo.jpg")
        .into(imageView);

#perfmatters #protip É importante que só haja uma instância desse objeto para evitar problemas de memória! Sendo assim, implemente um Singleton, e caso precise de um Context, passe o getApplicationContext() para ele ;)

4br4ç05,
nglauber