Android: сделать анимацию из неподвижных изображений
У меня есть серия неподвижных изображений и всего более 500 изображений, представленных в каталоге с возможностью рисования. Мне нужно сделать анимацию (загружать около 20 изображений в секунду). Я хочу, чтобы он работал плавно и без исключения из памяти.
У меня есть идея сделать это, чтобы изображения в течение от 2 до 3 секунд (от 40 до 60 изображений) должны были загружаться в память и отображаться, а затем они должны были удаляться (освобождать память), а затем изображения в течение следующих 2-3 секунд должны нагрузки. Этот метод может предотвратить исключение из памяти. Это просто идея, я не знаю, хорошая ли это идея или нет. Пожалуйста, помогите мне с некоторыми идеями с некоторым кодом, чтобы пойти... Если моя идея намного лучше и может работать, пожалуйста, скажите мне, какой код поможет сделать это.
Прочитав ответы и сделав так, как вы предлагаете, я написал такой код:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/llMain">
<ViewFlipper android:id="@+id/imageflipper"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView android:id="@+id/ImageView01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerInside"
android:layout_gravity="center" />
</ViewFlipper>
</LinearLayout>
и вот мой код для анимации:
public class Animation extends Activity {
ViewFlipper flipper;
int myIndex = 216;
private final Handler handler = new Handler();
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
flipper=(ViewFlipper)findViewById(R.id.imageflipper);
doTheAutoRefresh();
//displayData();
}
private void doTheAutoRefresh() {
handler.postDelayed(new Runnable() {
public void run(){
displayData(); // this is where you put your refresh code
doTheAutoRefresh();
}
}, 30);
}
private void displayData()
{
Resources r = getResources();
if(myIndex > 230){
myIndex = 216;
ImageView myImg = (ImageView)findViewById(R.id.ImageView01);
myImg.setImageResource(r.getIdentifier("drum0" + myIndex, "drawable", "com.vt.animation"));
myIndex += 1;
flipper.showNext();
}
else{
ImageView myImg = (ImageView)findViewById(R.id.ImageView01);
myImg.setImageResource(r.getIdentifier("drum0" + myIndex, "drawable", "com.vt.animation"));
myIndex += 1;
flipper.showNext();
}
}
}
но он очень медленный. Я установил время обновления до 30 миллисекунд, но на самом деле он не освежает слишком быстро, а время его обновления составляет около 1 секунды. Любое предложение сделать его быстрым, чтобы почувствовать себя настоящей анимацией?
Спасибо,
Ответы
Ответ 1
OK. Самая большая проблема и самое простое решение, с которым мне пришлось поехать после стольких дней. Я бы никогда не ожидал, что это будет так легко сделать...: D
Я использовал как обработчик, так и таймер для достижения только с представлением изображения, без флиппера, без аниматора вообще ничего... Вот мое решение:
----- файл main.xml -----
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/background">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageView1">
</ImageView>
И вот как я это сделал:
public class MainActivity extends Activity {
private ImageView _imagView;
private Timer _timer;
private int _index;
private MyHandler handler;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
handler= new MyHandler();
_imagView=(ImageView) findViewById(R.id.imageView1);
_index=0;
_timer= new Timer();
_timer.schedule(new TickClass(), 500, 200);
}
private class TickClass extends TimerTask
{
@Override
public void run() {
// TODO Auto-generated method stub
handler.sendEmptyMessage(_index);
_index++;
}
}
private class MyHandler extends Handler
{
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
try {
Bitmap bmp= BitmapFactory.decodeStream(MainActivity.this.getAssets().open("drum_"+_index+".png"));
_imagView.setImageBitmap(bmp);
Log.v("Loaing Image: ",_index+"");
} catch (IOException e) {
// TODO Auto-generated catch block
Log.v("Exception in Handler ",e.getMessage());
}
}
}
}
Примечание. Я поместил все мои изображения в каталог ресурсов.
Это настолько просто, насколько это возможно, ничего не поделаешь...
Надеюсь, это будет полезно для тех, кто хочет выглядеть так:)
Ответ 2
Используйте FrameAnimation, например, в res/drawable/movie.xml
:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item android:drawable="@drawable/frame1" android:duration="50" />
<item android:drawable="@drawable/frame2" android:duration="50" />
<item android:drawable="@drawable/frame3" android:duration="50" />
etc...
</animation-list>
А затем в Java:
imageView.setBackgroundResource(R.drawable.movie);
AnimationDrawable anim = (AnimationDrawable) imageView.getBackground();
anim.start();
Ответ 3
Загрузка нескольких изображений очень дорого.
Я думаю, что лучше загрузить одно изображение, содержащее все движения этой определенной анимации. Анимационная полоса.
private Bitmap animation = BitmapFactory.decodeResource(getResources(), R.drawable.myPng);
Идея заключается в перемещении растрового изображения.
Ответ 4
Ну, я использую viewFlipper, переключаюсь между представлениями. Хорошая вещь об этом заключается в том, что вы можете видеть, как предыдущее изображение сдвигается, когда новый слайд.
Метод отображения внутри изображения:
if (direction == NEXT) {
viewFlipper.setInAnimation(slideLeftIn);
viewFlipper.setOutAnimation(slideLeftOut);
if (currImg < max)
currImg++;
if (currImg == max)
currImg = 0;
if (currentView == 0) {
currentView = 1;
ImageView iv = (ImageView) findViewById(R.id.ImageView02);
iv.setImageResource(images[currImg]);
} else if (currentView == 1) {
currentView = 2;
ImageView iv = (ImageView) findViewById(R.id.ImageView03);
iv.setImageResource(images[currImg]);
} else {
currentView = 0;
ImageView iv = (ImageView) findViewById(R.id.ImageView01);
iv.setImageResource(images[currImg]);
}
viewFlipper.showNext();
}
else if (direction == PREV) {
viewFlipper.setInAnimation(slideRightIn);
viewFlipper.setOutAnimation(slideRightOut);
if (currImg > 0)
currImg--;
else if (currImg <= 0)
currImg = (max-1);
if (currentView == 0) {
currentView = 2;
ImageView iv = (ImageView) findViewById(R.id.ImageView03);
iv.setImageResource(images[currImg]);
} else if (currentView == 2) {
currentView = 1;
ImageView iv = (ImageView) findViewById(R.id.ImageView02);
iv.setImageResource(images[currImg]);
} else {
currentView = 0;
ImageView iv = (ImageView) findViewById(R.id.ImageView01);
iv.setImageResource(images[currImg]);
}
viewFlipper.showPrevious();
И внутри XML файла:
<ViewFlipper android:id="@+id/imageflipper"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView android:id="@+id/ImageView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:layout_gravity="center" />
<ImageView android:id="@+id/ImageView02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:layout_gravity="center" />
<ImageView android:id="@+id/ImageView03"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:layout_gravity="center" />
</ViewFlipper>