Vra

As ek die URL vir groot geanimeerde gif en ek wou 'n youtube soos aktiwiteit wat die animasie in 'n streaming manier vertoon maak. Hoe doen ek

  1. stroom in die beeld?
  2. kry dit vertoon doen met werklike animasie?

Ek weet ImageView is nie die antwoord as dit wys net die eerste raam.

'n bonus sal toegang tot sy buffer status sodat ek kan sinchroniseer stroom klank sowel - dit is deel van 'n YTMND kyker aansoek. Terwyl ek 'n diens wat die openbare gif lêers transform coderen in 'n mooier formaat kan skep, sou ek die jeug om te funksioneer sonder bykomende afhanklikhede hou.

Was dit nuttig?

Oplossing

Die algemene skets van die oplossing is om diens persoonlike View wat trek vra 'n Movie om homself van tyd tot tyd te vestig op die Canvas gebruik.

Die eerste stap is die bou van die Movie byvoorbeeld. Daar is fabriek genoem decodeStream dat 'n fliek gegee 'n InputStream kan maak, maar dit is nie genoeg om die stroom te gebruik van 'n UrlConnection. As jy dit probeer sal jy 'n IOException kry wanneer die film loader probeer reset 'n beroep op die stroom. Die hack, jammer want dit is, is om 'n geskei BufferedInputStream gebruik met 'n hand-stel mark om dit te vertel om genoeg data wat reset sal nie dof brand te red. Gelukkig kan die URLConnection ons vertel hoeveel data om te verwag. Ek sê dit hack is jammer, want dit effektief vereis dat die hele beeld te gebuffer in geheue (dit is nie 'n probleem vir die lessenaar programme, maar dit is 'n ernstige saak op 'n geheue beperk mobiele toestel).

Hier is 'n snip van die Movie opstel kode:

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();

Volgende, moet jy 'n siening dat hierdie Movie sal vertoon te skep. A subklas van View met 'n persoonlike onDraw sal die truuk doen (die veronderstelling dat dit toegang tot die Movie jy geskep met die vorige kode het).

@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);
    }
}

Die vertoning sal self nie die sneller te teruggeteken sonder hulp, en blindelings roeping invalidate() aan die einde van onDraw is net 'n energie-afval. In 'n ander draad (waarskynlik die een wat jy gebruik om die beeld data te laai), kan jy boodskappe stuur na die hoof draad, vra vir die oog op ongeldig teen 'n bestendige (maar nie mal) pas.

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();

'n baie mooi oplossing sou allerhande soet vordering bars en foutopsporing het, maar die kern is hier.

Ander wenke

gly bewys mees maklik en doeltreffende manier om dit reg te kry met net een lyn van kode: -

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

Die resultaat is hier: -

 betree beeld beskrywing hier

Gif geneem uit hier http://giphy.com/search/big-gif/3

jar Voeg uit hier: - https://github.com/bumptech/glide/releases

Miskien AnimationDrawable kan vir jou werk? EDIT: Nie as jy wil om te laai van 'n URL soos hierdie post is oor. Jammer

http://developer.android.com/reference/android/ grafiese / tekenbaar / AnimationDrawable.html

Na gelang van die kompleksiteit van die GIF maw as dit is 'n eenvoudige laai / vordering aanwyser jy kan die GIF breek, spaar elke beeld afsonderlik en gebruik die Android Raamwerk se AnimationDrawable.

Vir eenvoudige vordering bars dit kan minder gevoelig vir foute, miskien selfs meer performante wees.

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top