android中使用imageview显示Gif图片

http://blog.csdn.net/riyuegonghe/article/details/9283479

http://weavora.com/blog/2012/02/07/android-how-to-use-animated-gif/

To date Android platform supports a sufficiently large number of media formats. See documentation here. Among the declared graphic formats you’ll find the one we are interested – GIF. Generally speaking this format does not cause any difficulties until you’ll try to use a GIF file with animation. In this case, the standard class ImageViewdisplays GIF file as a usual static image. Doing search you can find forums stating that Android platform doesn’t fully support GIF, that animated GIF files cannot be used. Nevertheless you can still solve this problem and I’ll show you how.

There are at least two ways:

It is difficult to say which solution is better, however there is one important point. Although WebView is a part of any Android SDK, the ability to play animated GIF files only appeared from version Android 2.2 (API level 8). So if you plan support for vide range of devices, then second option is likely more acceptable for you. I’ll further focus on it.

It is not quite fair to say that class Movie is well documented. Otherwise, this article probably would be useless :-) So, let’s try to create a separate component that can play animated GIF files using class Movie.

OK, creating a new class GIFView, inherited from View:

1234567891011121314151617181920
         
         
package com . wvr . widget ;
import android.content.Context ;
import android.util.AttributeSet ;
import android.view.View ;
 
public class GIFView extends View {
 
public GIFView ( Context context ) {
super ( context );
}
 
public GIFView ( Context context , AttributeSet attrs ) {
super ( context , attrs );
}
 
public GIFView ( Context context , AttributeSet attrs , int defStyle ) {
super ( context , attrs , defStyle );
}
 
}
view raw GIFView.java hosted with ❤ by  GitHub

Now let’s add new variable of type Movie to our class and initialize it

1234567891011121314151617181920212223242526272829303132333435
         
         
package com . wvr . widget ;
 
import java.io.InputStream ;
import com.wvr.example.R ;
import android.content.Context ;
import android.graphics.Movie ;
import android.util.AttributeSet ;
import android.view.View ;
 
public class GIFView extends View {
private Movie mMovie ;
 
public GIFView ( Context context ) {
super ( context );
initializeView ();
}
 
public GIFView ( Context context , AttributeSet attrs ) {
super ( context , attrs );
initializeView ();
}
 
public GIFView ( Context context , AttributeSet attrs , int defStyle ) {
super ( context , attrs , defStyle );
initializeView ();
}
 
private void initializeView () {
//R.drawable.loader - our animated GIF
InputStream is = getContext (). getResources (). openRawResource ( R . drawable . loader );
mMovie = Movie . decodeStream ( is );
}
 
}
view raw GIFView2.java hosted with ❤ by  GitHub

OK, now Movie object is initialized and we just need to draw it. We will use onDraw(Canvas) method for this purpose, but before that, we must let Movie object know what exact part of GIF file it should draw. To do this we need a separate variable movieStart of long type, which we assign SystemClock.uptimeMillis() value. In this case we will know when the movie was started and can calculate how much time has passed.

123456789101112131415
         
         
@Override
protected void onDraw ( Canvas canvas ) {
canvas . drawColor ( Color . TRANSPARENT );
super . onDraw ( canvas );
long now = android . os . SystemClock . uptimeMillis ();
if ( movieStart == 0 ) {
movieStart = now ;
}
if ( movie != null ) {
int relTime = ( int ) (( now - movieStart ) % movie . duration ());
movie . setTime ( relTime );
movie . draw ( canvas , getWidth () - movie . width (), getHeight () - movie . height ());
this . invalidate ();
}
}
view raw onDraw.java hosted with ❤ by  GitHub

All we need now is initialize GIFView in our Activity class

12345678
         
         
public class AnimatedGIFActivity extends Activity {
@Override
public void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
GIFView gifView = new GIFView ( this );
setContentView ( gifView );
}
}
view raw onCreate.java hosted with ❤ by  GitHub

Now let’s add the possibility to pass GIF id as a parameter

12345678910111213141516171819
         
         
private int gifId ;
 
public void setGIFResource ( int resId ) {
this . gifId = resId ;
initializeView ();
}
 
public int getGIFResource () {
return this . gifId ;
}
 
private void initializeView () {
if ( gifId != 0 ) {
InputStream is = getContext (). getResources (). openRawResource ( gifId );
movie = Movie . decodeStream ( is );
movieStart = 0 ;
this . invalidate ();
}
}
view raw GIF_Param.java hosted with ❤ by  GitHub

Here is how the Activity class should look:

123456
         
         
public void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
GIFView gifView = new GIFView ( this );
gifView . setGIFResource ( R . drawable . loader );
setContentView ( gifView );
}
view raw onCreate.java hosted with ❤ by  GitHub

Another good practice is using components in XML markup. So, let’s also do this. For this purpose I’ll create fileattrs.xml (res/values/attrs.xml) with the following structure:

12345
         
         
<resources>
<declare-styleable name= "GIFView" >
<attr name= "src" format= "reference" />
</declare-styleable>
</resources>
view raw attrs.xml hosted with ❤ by  GitHub

Now we just need to read XML-attributes in our GIFView class:

12345678910
         
         
private void setAttrs ( AttributeSet attrs ) {
if ( attrs != null ) {
TypedArray a = getContext (). obtainStyledAttributes ( attrs , R . styleable . GIFView , 0 , 0 );
String gifSource = a . getString ( R . styleable . GIFView_src );
//little workaround here. Who knows better approach on how to easily get resource id - please share
String sourceName = Uri . parse ( gifSource ). getLastPathSegment (). replace ( ".gif" , "" );
setGIFResource ( getResources (). getIdentifier ( sourceName , "drawable" , getContext (). getPackageName ()));
a . recycle ();
}
}
view raw setAttrs.java hosted with ❤ by  GitHub

After this we are able to use GIFView in XML markup the following way:

main.xml

123456789101112
         
         
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"
xmlns:components= "http://schemas.android.com/apk/res/com.wvr.example"
android:layout_width= "fill_parent"
android:layout_height= "fill_parent"
android:orientation= "vertical" >
 
<com.wvr.widget.GIFView
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
components:src= "@drawable/loader" />
</LinearLayout>
view raw main.xml hosted with ❤ by  GitHub

Our Activity class looks the following way:

1234567
         
         
public class AnimatedGIFActivity extends Activity {
@Override
public void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView ( R . layout . main );
}
}
view raw AnimatedGIFActivity.java hosted with ❤ by  GitHub

That’s it. Have you ever used such approach or maybe you have some better solution – please let us know.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值