Как сделать так, чтобы в Drawable быстро менялись активы изображений (jpg) для короткой анимации? - PullRequest
0 голосов
/ 20 февраля 2019

Я хочу сделать приложение для игры в кости с короткой анимацией, состоящей из изображений.Я создал 100 изображений JPG для каждого из 20 возможных результатов (кубик d20).Дело в том, что я не могу знать точные имена необходимых файлов после броска, так как это случайно.Поэтому я не могу использовать setImageResource, так как мне нужно точное имя файла для него.

Я решил попробовать использовать ресурсы, поскольку я могу выбрать .getString вместо точного имени файла (все JPG-файлы названы в формате d20 +номер результата + номер кадра анимации).Приложение работает вроде бы нормально, но картинки на экране не меняются, пока все не закончится, а затем появляется только последнее изображение анимации и в меньшем формате, чем должно быть.

Может ли кто-нибудь указать на мою ошибку?

Вот код:

import android.content.res.AssetManager;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import java.io.IOException;
import java.io.InputStream;
import java.util.Random;

public class MainActivity extends AppCompatActivity {



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

}
public Random random = new Random();


public void Throw(View view) throws InterruptedException {
    ImageView dice = findViewById(R.id.imageD20);
    dice.setImageResource(R.drawable.d2002030);
    int result = random.nextInt(19); // throwing dice...
    long startTime = 0;
    long delayTime = 0;
    String fileNameStr = new String();


    for (int i = 0; i<=100; i++) {       // animation
        fileNameStr = getResources().getString(R.string.fileName, result, i + 1);
       InputStream img = null;
       AssetManager mngr = this.getAssets();
        try {
           InputStream ims = getAssets().open(fileNameStr);
           Drawable image = Drawable.createFromStream(ims, null);
           dice.setImageDrawable(image);
                      }
        catch(IOException ex) {
            ex.printStackTrace();
        }
        startTime = System.currentTimeMillis();
        delayTime = startTime+10;
        while(System.currentTimeMillis() < delayTime);
   }


}
}

И ресурсы (откуда я получаю строку имени файла):

<resources>
<string name="app_name">D20dice</string>
<string name="fileName">""d20%1$02d%2$03d".jpg"</string>
</resources>

Я узнал, как сделать это без ресурсов, просто с помощью обычных ресурсов через getResources (). GetIdentifier ().С его помощью я могу найти идентификатор ресурса с помощью строковой переменной.Ниже приводится новый код для Throw:

 public void Throw(View view) throws InterruptedException {
    ImageView dice = findViewById(R.id.imageD20);
    dice.setImageResource(R.drawable.d2002030);
    int result = random.nextInt(19); // throwing dice...
    long startTime = 0;
    long delayTime = 0;
    String fileNameStr = new String();
    int resID;

    for (int i = 0; i<=100; i++) {       // animation

        fileNameStr = getResources().getString(R.string.fileName, result, i + 1);

        resID = getResources().getIdentifier(fileNameStr , "drawable", getPackageName());

        dice.setImageResource(resID);
        dice.invalidate();
        startTime = System.currentTimeMillis();
        delayTime = startTime+10;
        while(System.currentTimeMillis() < delayTime);
    }

}

Но все тот же, он показывает только первое и последнее изображение (но последнее изображение по крайней мере в правильном размере).

I`попробовал AnimationDrawable: теперь для первого броска я вижу первый и последний кадр только снова, а на втором броске приложение вылетает.Вот этот код:

 public void Throw(View view) throws InterruptedException {
    ImageView dice = findViewById(R.id.imageD20);
    dice.setImageResource(R.drawable.d2002030);
    int result = random.nextInt(19); // throwing dice...
    String fileNameStr = new String();
    Drawable frame;
    AnimationDrawable diceAnimation = new AnimationDrawable();
    diceAnimation.setOneShot(true);

    int resID;

    for (int i = 0; i<=100; i++) {       // animation

        fileNameStr = getResources().getString(R.string.fileName, result, i + 1);

        resID = getResources().getIdentifier(fileNameStr , "drawable", getPackageName());
        frame = getResources().getDrawable(resID);
        diceAnimation.addFrame(frame, 200);
         }


    dice.setBackground(diceAnimation);
    diceAnimation.start();


}

1 Ответ

0 голосов
/ 14 мая 2019

Проблема, вероятно, заключалась в том, что я изначально установил фон с помощью setImageResource, а затем загрузил анимацию в фон (setBackground (diceAnimation)).Но даже после того, как проблема была решена, анимация воспроизводилась после долгой задержки перед стартом.кажется, что для AnimationDrawble 100 кадров 320х240 - это слишком много.Я, наконец, решил проблему, преобразовав все анимации в GIF и выведя их через подключенный android-gif-drawable: https://github.com/koral--/android-gif-drawable

...