【问题标题】:How to display GIF file如何显示 GIF 文件
【发布时间】:2017-02-14 18:46:37
【问题描述】:

我使用这个library 作为显示“gif”文件的指南。当在drawable中使用保存的gif时,它会正确显示gif我这样称呼它

<pl.droidsonroids.gif.GifImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/imgView1"
    android:src="@drawable/gifFile"
    />

但是当删除 src 并尝试像这样在 Activity 中初始化 GifImageView 时

 GifImageView gifFromFile = (GifImageView) findViewById(R.id.imgView1);
gifFromFile.setImageBitmap(Utils.getBitmapImagefromStorage(context, imageHome));

getBitmapImagefromStorage 获取路径,imageHome 获取文件名,gif 文件不会像图像一样播放其唯一显示。据说If given drawable is not a GIF then mentioned Views work like plain ImageView and ImageButton. 但我提供的文件是gif。我想知道我是否正确使用它。

该文件也可以是pnggif,所以我需要支持这两个。

【问题讨论】:

标签: android gif


【解决方案1】:

来自 XML

最简单的方法是像使用普通 ImageView 一样使用 GifImageView(或 GifImageButton):

<pl.droidsonroids.gif.GifImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:src="@drawable/src_anim"
    android:background="@drawable/bg_anim"
    />

如果 android:src 和/或 android:background 声明的 drawables 是 GIF 文件,那么它们将被自动识别为 GifDrawables 并具有动画效果。如果给定的 drawable 不是 GIF,那么提到的 View 就像普通的 ImageView 和 ImageButton 一样工作。

GifTextView 允许您将 GIF 用作复合可绘制对象和背景。

<pl.droidsonroids.gif.GifTextView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:drawableTop="@drawable/left_anim"
    android:drawableStart="@drawable/left_anim"
    android:background="@drawable/bg_anim"
    />

来自 Java 代码 GifImageView、GifImageButton 和 GifTextView 也实现了 setter 的钩子。所以可以通过调用setImageResource(int resId)setBackgroundResource(int resId)来设置动画GIF

GifDrawable 可以直接从各种来源构建:

 //asset file
    GifDrawable gifFromAssets = new GifDrawable( getAssets(), "anim.gif" );

    //resource (drawable or raw)
    GifDrawable gifFromResource = new GifDrawable( getResources(), R.drawable.anim );

    //byte array
    byte[] rawGifBytes = ...
    GifDrawable gifFromBytes = new GifDrawable( rawGifBytes );

    //FileDescriptor
    FileDescriptor fd = new RandomAccessFile( "/path/anim.gif", "r" ).getFD();
    GifDrawable gifFromFd = new GifDrawable( fd );

    //file path
    GifDrawable gifFromPath = new GifDrawable( "/path/anim.gif" );

    //file
    File gifFile = new File(getFilesDir(),"anim.gif");
    GifDrawable gifFromFile = new GifDrawable(gifFile);

    //AssetFileDescriptor
    AssetFileDescriptor afd = getAssets().openFd( "anim.gif" );
    GifDrawable gifFromAfd = new GifDrawable( afd );

    //InputStream (it must support marking)
    InputStream sourceIs = ...
    BufferedInputStream bis = new BufferedInputStream( sourceIs, GIF_LENGTH );
    GifDrawable gifFromStream = new GifDrawable( bis );

    //direct ByteBuffer
    ByteBuffer rawGifBytes = ...
    GifDrawable gifFromBytes = new GifDrawable( rawGifBytes );

如果不再需要 GifDrawable,InputStream 会在终结器中自动关闭,因此您无需显式关闭它们。调用recycle() 也会关闭底层输入源。

请注意,所有输入源都需要能够倒回到开头。需要正确播放动画 GIF(动画是可重复的),因为后续帧是根据需要从源解码的。

参考:https://github.com/koral--/android-gif-drawable

【讨论】:

    【解决方案2】:
    GifTextView gifImageView;
    

    在 onCreate 中

    gifImageView = (GifTextView) findViewById(R.id.imageView);
    

    在onCreate中调用该方法

    public void playGif(){
            Animation fadeout = new AlphaAnimation(1.f, 1.f);
            fadeout.setDuration(2500); // You can modify the duration here
            fadeout.setAnimationListener(new Animation.AnimationListener() {
    
                @Override
                public void onAnimationStart(Animation animation) {
                    gifImageView.setBackgroundResource(R.drawable.gif_image);//your gif file
                }
    
                @Override
                public void onAnimationRepeat(Animation animation) {
                }
    
                @Override
                public void onAnimationEnd(Animation animation) {
    
                }
            });
            gifImageView.startAnimation(fadeout);
        }
    

    在你的布局文件中

    <pl.droidsonroids.gif.GifTextView
            android:id="@+id/imageView"
            android:layout_width="fill_parent"
            android:scaleType="fitXY"
            android:layout_height="fill_parent"
            />
    

    【讨论】:

    • 我可以用这个setImageBitmap(Utils.getBitmapImagefromStorage(context, imageHome));代替setBackgroundResource(R.drawable.gif_image)吗?
    • 我有Cannot resolve method setImageBitmap 除了使用R.drawable 还有其他方法吗?
    • 将您的位图转换为可绘制然后设置它。请参考:stackoverflow.com/questions/2415619/…
    • 使用Drawable d = new BitmapDrawable(getResources(), yourBitmap);然后使用 d 作为 drawable 并将其设置为 imageView
    • in getResources() 我应该放路径?
    【解决方案3】:

    尝试通过这种方式在您的应用中使用 GIF

    public class PlayGifView extends View{
    
         private static final int DEFAULT_MOVIEW_DURATION = 1000;
    
         private int mMovieResourceId;
         private Movie mMovie;
    
         private long mMovieStart = 0;
         private int mCurrentAnimationTime = 0;
    
         @SuppressLint("NewApi")
         public PlayGifView(Context context, AttributeSet attrs) {
             super(context, attrs);
    
            /**
             * Starting from HONEYCOMB have to turn off HardWare acceleration to draw
             * Movie on Canvas.
             */
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                setLayerType(View.LAYER_TYPE_SOFTWARE, null);
            }
        }
    
         public void setImageResource(int mvId){
             this.mMovieResourceId = mvId;
        mMovie = Movie.decodeStream(getResources().openRawResource(mMovieResourceId));
        requestLayout();
    }
    
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if(mMovie != null){
            setMeasuredDimension(mMovie.width(), mMovie.height());
        }else{
            setMeasuredDimension(getSuggestedMinimumWidth(), getSuggestedMinimumHeight());
        }
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        if (mMovie != null){
            updateAnimtionTime();
            drawGif(canvas);
            invalidate();
        }else{
            drawGif(canvas);
        }
    }
    
    private void updateAnimtionTime() {
        long now = android.os.SystemClock.uptimeMillis();
    
        if (mMovieStart == 0) {
            mMovieStart = now;
        }
        int dur = mMovie.duration();
        if (dur == 0) {
            dur = DEFAULT_MOVIEW_DURATION;
        }
        mCurrentAnimationTime = (int) ((now - mMovieStart) % dur);
    }
    
    private void drawGif(Canvas canvas) {
        mMovie.setTime(mCurrentAnimationTime);
        mMovie.draw(canvas, 0, 0);
        canvas.restore();
    }
    
    }
    

    在你的活动课上

    PlayGifView pGif = (PlayGifView) findViewById(R.id.viewGif);
    pGif.setImageResource(R.drawable.yourgifimage);
    

    然后在你的 XML 中

    <YourPackageName.PlayGifView
                android:id="@+id/viewGif"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center" />
    

    【讨论】:

    • 我得到这个 java.lang.NullPointerException: Attempt to call virtual method 'boolean android.graphics.Movie.setTime(int)' on an null object reference at ......drawGif( GifImageView.java:85)
    • @RalucaLucaci 在哪一行?
    【解决方案4】:

    我尝试使用GifDrawable

    File gifFile = new File(context.getExternalFilesDir(null)
                        .getAbsolutePath(), imageHome);
    GifDrawable gifFromPath  = new GifDrawable(gifFile);
    

    然后我不使用setImageBitmap,而是使用setImageDrawable

    GifImageView gifImageView = (GifImageView) findViewById(R.id.textViewDealFinder);
            gifImageView.setImageDrawable(gifFromPath);
    

    【讨论】:

      猜你喜欢
      • 2013-05-04
      • 1970-01-01
      • 2011-02-20
      • 2020-12-24
      • 1970-01-01
      • 2022-01-15
      • 2019-04-30
      相关资源
      最近更新 更多