Android ImageView中的750帧透明PNG动画,每秒23帧
我有一个活动,其中两个ImageView设置为全屏320 x 480 我需要播放一个动画,但在VM用完之前,使用AnimatedRavable和xml数组播放的动画不能超过50个 我试着用一个循环来切换PNG,这样我就可以在一路上做其他的事情了。 例如,在第120、180和250帧处振动,并在第400帧处播放另一个动画 下面的代码可以工作,但是ImageView需要180-280ms才能在模拟器上更新。所以我需要将thread.sleep设置为大于280-300,否则我将开始丢失帧。我需要一种更快的方法来更新imageview。有没有更快的小部件 一些帧的图像不需要更改或是空白的,所以当动画持续746帧时,我实际上只需要245帧。因此,我已经从drawables文件夹中删除了未更改或空白的框架,当找不到时,代码会跳过它们。这将所有图像的总大小减少到9mb 这是我的第一个安卓应用,如果我做得不对,我很抱歉。我会听取任何关于如何改进的建议。:-) 有人能想出更好的方法吗?救命!!(同样的逻辑在iPhone上也适用) 活动\u main.xmlAndroid ImageView中的750帧透明PNG动画,每秒23帧,android,eclipse,animation,png,imageview,Android,Eclipse,Animation,Png,Imageview,我有一个活动,其中两个ImageView设置为全屏320 x 480 我需要播放一个动画,但在VM用完之前,使用AnimatedRavable和xml数组播放的动画不能超过50个 我试着用一个循环来切换PNG,这样我就可以在一路上做其他的事情了。 例如,在第120、180和250帧处振动,并在第400帧处播放另一个动画 下面的代码可以工作,但是ImageView需要180-280ms才能在模拟器上更新。所以我需要将thread.sleep设置为大于280-300,否则我将开始丢失帧。我需要一种更
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<ImageView
android:id="@+id/background"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:scaleType="fitXY"
android:src="@drawable/imgbackground"
android:visibility="visible" />
<ImageView
android:id="@+id/animLayer"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:visibility="visible" />
</RelativeLayout>
xmlns:tools=”http://schemas.android.com/tools"
android:layout\u width=“匹配父项”
android:layout\u height=“match\u parent”
工具:context=“.MainActivity”>
MainActivity.java
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<ImageView
android:id="@+id/background"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:scaleType="fitXY"
android:src="@drawable/imgbackground"
android:visibility="visible" />
<ImageView
android:id="@+id/animLayer"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:visibility="visible" />
</RelativeLayout>
package com.test.pngloop
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.widget.ImageView;
public class MainActivity extends Activity {
private static final String TAG = null;
public int iFrameCount = 0;
public ImageView myIV;
public String myString;
long startTime;
long endTime;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//define the IV here so it's done only once
myIV = (ImageView) findViewById(R.id.animLayer);
}
@Override
protected void onStart()
{
super.onStart();
Thread thr1 = new Thread(r1);
thr1.start();
}
Runnable r1 = new Runnable()
{
public void run()
{
while (iFrameCount< 747)
{
runOnUiThread(new Runnable()
{
public void run()
{
iFrameCount++;
String image="image" + iFrameCount;
int resID = getResources().getIdentifier(image, "drawable", getPackageName());
if (resID != 0) //if there is no image/change for this frame skip it
{
myString="iFrameCount: " + iFrameCount;
Log.d(TAG, myString);
//speed the same between setImageResource & setBackgroundResource
//myIV.setImageResource(resID);
//myIV.postInvalidate();
startTime = System.currentTimeMillis();
myIV.setBackgroundResource(resID);
endTime = System.currentTimeMillis();
System.out.println("setBackground took: " + (endTime - startTime) + " milliseconds");
}
else
{ //we can skip frames 1-119, 209-251, 272-322, 416-472 & 554-745 (as no change from previous frame)
myString="File skipped: " + iFrameCount;
Log.d(TAG, myString);
}
}
});
try
{
Thread.sleep(300);
}
catch (InterruptedException iex) {}
}
Log.d(TAG, "Finished playing all frames");
}
};
package com.test.pngloop
导入android.os.Bundle;
导入android.app.Activity;
导入android.util.Log;
导入android.widget.ImageView;
公共类MainActivity扩展了活动{
私有静态最终字符串标记=null;
公共整数iframecont=0;
公共图像视图myIV;
公共字符串myString;
长启动时间;
长时间;
@凌驾
创建时受保护的void(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//在这里定义IV,以便只执行一次
myIV=(ImageView)findViewById(R.id.animLayer);
}
@凌驾
受保护的void onStart()
{
super.onStart();
螺纹thr1=新螺纹(r1);
thr1.start();
}
Runnable r1=新的Runnable()
{
公开募捐
{
而(iFrameCount<747)
{
runOnUiThread(新的Runnable()
{
公开募捐
{
iFrameCount++;
字符串image=“image”+iframecont;
int resID=getResources().getIdentifier(图像,“可绘制”,getPackageName());
if(resID!=0)//如果此帧没有图像/更改,请跳过它
{
myString=“iFrameCount:”+iFrameCount;
Log.d(TAG,myString);
//setImageResource和setBackgroundResource之间的速度相同
//myIV.setImageResource(剩余);
//myIV.postInvalidate();
startTime=System.currentTimeMillis();
myIV.挫折资源(剩余);
endTime=System.currentTimeMillis();
println(“挫折发生时间:”+(endTime-startTime)+“毫秒”);
}
其他的
{//我们可以跳过第1-119、209-251、272-322、416-472和554-745帧(与前一帧相同)
myString=“跳过文件:”+iframecont;
Log.d(TAG,myString);
}
}
});
尝试
{
睡眠(300);
}
捕获(中断异常iex){}
}
Log.d(标记“播放完所有帧”);
}
};
}现在,通过将每个图像(用于动画)的大小减小到最小的垂直条带以适合对象,我可以将帧速率提高到接近每秒20帧 我是在阅读了有关使用精灵表制作游戏动画的内容后想到这个主意的,在游戏动画中,精灵会移动单个图像,并通过一个小窗口查看所需的帧。精灵不是我的目的,太多的框架精灵表将是135mb 图像现在只有480x150(每个31-54KB),而不是全屏。ImageView高度设置为fill_parent,ImageView宽度设置为wrap_内容,因此它仍然会自动缩放到不同的屏幕大小 我发现现在文件更小,加载速度更快,现在接近可接受的动画帧速率。希望这对其他尝试同样方法的人有所帮助。更新:我已经能够在实际的Android设备(LG optimus L5 480x320屏幕)上获得大约13帧(70毫秒循环)的速度。我只能从模拟器中获得5fps(200ms循环),而不会丢失帧。有人找到了更快播放大型动画的解决方案吗?将动画.Drawable拆分为小卡盘,然后一个接一个地播放,怎么样?更新2:通过将每个图像的大小减小到最小的水平条以适合对象,我现在能够将帧速率提高到接近每秒20帧。图像现在只有480 x 150,而不是全屏。ImageView高度设置为fill_parent,ImageView宽度设置为wrap_内容,这样我仍然可以缩放。我猜文件要小得多,加载速度也快得多。我从其他帖子中得到了关于使用精灵制作游戏动画的想法。希望这对其他人有帮助。