简而言之,我有一个 Activity A,它已应用setContentView(R.id.layout_a)
,A 将运行 5 秒。
我尝试定义一个自定义 View 类并使用 Movie 类加载 gif,然后将自定义视图附加到,layout_a
但它显示为空白。
网络视图方法
我试过WebView,它可以很好地显示gif,但是gif只有在我第一次启动这个活动时才能动画。当稍后的活动 A 启动时,它只会显示最后一帧。
我试过WebView.reload()
但不甜。
这是我尝试应用 WebView 时的代码:
public class activityA extends Activity {
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.activity_a);
WebView splashFrame = (WebView)findViewById(R.id.splashFrame);
splashFrame.setBackgroundColor(Color.TRANSPARENT);
splashFrame.loadDataWithBaseURL("file:///android_res/drawable/", "<img align='middle' src='face_morph_gif.gif' width='100%' />", "text/html", "utf-8", null);
splashFrame.reload();
Handler handler = new Handler();
// run a thread after 3 seconds to start the home screen
handler.postDelayed(new Runnable() {
@Override
public void run() {
// make sure we close the splash screen so the user won't come back when it presses back key
finish();
// start the home screen
Intent intent = new Intent(activityA.this, activityB.class);
SplashScreenActivity.this.startActivity(intent);
}
}, 5000);
}
}
所以我的问题1来了:当我启动活动A时,如何让这个gif从头开始播放?我注意到当我使用 Safari/Chrome 打开这个 gif 时,它只会播放一次,直到我手动刷新浏览器。
自定义视图方法
这是我正在研究的第一种方式,但我什至一次都找不到工作。
活动A代码:
public class activityA extends Activity {
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.activity_a);
Handler handler = new Handler();
// run a thread after 3 seconds to start the home screen
handler.postDelayed(new Runnable() {
@Override
public void run() {
// make sure we close the splash screen so the user won't come back when it presses back key
finish();
// start the home screen
Intent intent = new Intent(activityA.this, activityB.class);
SplashScreenActivity.this.startActivity(intent);
}
}, 5000);
}
}
客户视图:
public class GifView extends View {
public Movie mMovie;
public long mMovieStart;
public GifView(Context context) {
super(context);
setFocusable(true);
InputStream is = context.getResources().openRawResource(R.drawable.face_morph_gif);
mMovie = Movie.decodeStream(is);
}
public GifView(Context context, AttributeSet attr) {
super(context, attr);
setFocusable(true);
InputStream is = context.getResources().openRawResource(R.drawable.face_morph_gif);
mMovie = Movie.decodeStream(is);
}
public GifView(Context context, AttributeSet attr, int defStyle) {
super(context, attr, defStyle);
setFocusable(true);
InputStream is = context.getResources().openRawResource(R.drawable.face_morph_gif);
mMovie = Movie.decodeStream(is);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// canvas.drawColor(Color.TRANSPARENT);
final long now = SystemClock.uptimeMillis();
if (mMovieStart == 0) {
mMovieStart = now;
}
if (mMovie != null) {
int dur = mMovie.duration();
// Log.d("gif Canvas", "duration: " + mMovie.duration());
if (dur == 0) {
dur = 4000;
}
int relTime = (int)((now - mMovieStart) % dur);
mMovie.setTime(relTime);
mMovie.draw(canvas, 10, 10);
// Log.d("gif Canvas", mMovie.width() + "x" + mMovie.height());
invalidate();
}
}
@Override
protected void onMeasure(final int widthMeasureSpec,
final int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(getMeasuredWidth(), getMeasuredHeight());
}
}
以及 layout_a 的 xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/app_background"
tools:ignore="ContentDescription" >
<ImageView
... />
<ImageView
... />
<ImageView
... />
<ImageView
... />
<com.xxx.GifView
android:id="@+id/splashFrame"
android:layout_width="95dp"
android:layout_height="156dp"
android:visibility="visible" />
所以我的问题 2来了:为什么这个自定义视图不能显示 gif?我在方法中设置了断点onDraw
,我确信 mMovie 可以加载 gif(mMovie 可以返回正确的 gif 宽度和高度)
我知道让 gif 在 Android 上工作是一个相当古老的话题,AFAIK 有 3 种方法:
电影课
自定义视图
分割 GIF/使用 Android 动画
我不能使用第三种方式,因为我使用的 gif 有 100 帧,而且不便宜。
我已经阅读了所有教程和 SO 问题,但没有一个可以完成这项工作。
感谢您阅读我的问题。