Pergunta

Suponha que eu tenha o URL para um GIF animado grande e queria fazer uma atividade como o YouTube que exibe a animação de uma maneira de streaming. Como é que eu

  1. fluxo na imagem?
  2. Consegui -lo exibir com animação real?

Eu sei ImageView não é a resposta, pois mostra apenas o primeiro quadro.

Um bônus seria ter acesso ao seu status de buffer para que eu possa sincronizar o som de streaming também - isso faz parte de um Ytmnd Aplicação do visualizador. Embora eu possa criar um serviço que transcoda os arquivos públicos GIF em um formato melhor, gostaria que o aplicativo funcionasse sem dependências adicionais.

Foi útil?

Solução

O esboço geral da solução é usar empregar costume View que desenha pergunta um Movie para se desenhar para o Canvas periodicamente.

O primeiro passo é construir o Movie instância. Há fábrica chamada decodeStream que pode fazer um filme dado um InputStream Mas não é suficiente usar o fluxo de um UrlConnection. Se você tentar isso, você receberá um IOException Quando o carregador do filme tenta ligar reset no fluxo. O hack, por mais infeliz, é usar um separado BufferedInputStream com um conjunto manual mark para dizer para salvar dados suficientes que reset não falhará. Felizmente, o URLConnection pode nos dizer quantos dados esperam. Eu digo que esse hack é lamentável, porque exige efetivamente que toda a imagem seja buffer na memória (o que não é problema para aplicativos de desktop, mas é um problema sério em um dispositivo móvel com restrição de memória).

Aqui está um recorte do Movie Código de configuração:

URL url = new URL(gifSource);
URLConnection conn = url.openConnection();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
bis.mark(conn.getContentLength());
Movie movie = Movie.decodeStream(bis);
bis.close();

Em seguida, você precisa criar uma visão que exibirá isso Movie. Uma subclasse de View com um costume onDraw fará o truque (supondo que tenha acesso ao Movie você criou com o código anterior).

@Override protected void onDraw(Canvas canvas) {
    if(movie != null) {
        long now = android.os.SystemClock.uptimeMillis();
        int dur = Math.max(movie.duration(), 1); // is it really animated?
        int pos = (int)(now % dur);
        movie.setTime(pos);
        movie.draw(canvas, x, y);
    }
}

A visão não se aciona para ser redesenhada sem ajuda, e chamando cegamente invalidate() no fim de onDraw é apenas um desperdício de energia. Em outro thread (provavelmente aquele que você usou para baixar os dados da imagem), você pode postar mensagens no thread principal, pedindo que a visualização seja invalidada em um ritmo constante (mas não insano).

Handler handler = new Handler();
new Thread() {
    @Override public void run() {
        // ... setup the movie (using the code from above)
        // ... create and display the custom view, passing the movie

        while(!Thread.currentThread().isInterrupted()) {
            handler.post(new Runnable() {
                public void run(){
                    view.invalidate();
                }
            });
            try {
                Thread.sleep(50); // yields 20 fps
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}.start();

Uma solução muito boa teria todo tipo de doces barras de progresso e verificação de erros, mas o núcleo está aqui.

Outras dicas

Você tentou BitmapDecode?

Há um exemplo nas demos da API aqui.

Deslizar prove uma maneira mais fácil e eficiente de conseguir isso com apenas uma linha de código:-

Glide.with(getApplicationContext())
            .load(Uri.parse("https://media1.giphy.com/media/5ziaphcUWGKPu/200.gif"))
            .asGif().placeholder(R.drawable.ic_launcher).crossFade()
            .into(imageView);

O resultado está aqui:-

enter image description here

GIF tirado daqui http://giphy.com/search/big-gif/3

Adicionar jar daqui:- https://github.com/bumptech/glide/releases

Pode ser Animação drawable poderia funcionar para você? EDIT: Não se você deseja carregar de um URL como esta postagem. Desculpe

http://developer.android.com/reference/android/graphics/drawable/animationdrawable.html

Dependendo da complexidade do GIF, isto é, se for um indicador simples de carregamento/progresso, você poderá separar o GIF, salve cada imagem separadamente e usar o Animation Drawable da estrutura do Android.

Para barras de progresso simples, isso pode ser menos propenso a erros, talvez ainda mais com desempenho.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top