Posted at

[Android]アイコンをアニメーションさせる

More than 5 years have passed since last update.


完成イメージ

button.gif

AndroidではViewにアニメGIFを設定してもアニメーションが再生されません(ごめんなさい、試してません)。

そこで、FontAwesomeアイコンをパラパラまんがのように切り替えてアニメーションを実現します。

使える場面がものすごーーーーーく限定的だとは思いますが、参考までに...

それとサンプルではFontAwesomeアイコンを切り替えていますが、FontAwesomeはただの文字なので、同じやり方で文字をアニメーションさせることもできます。用途がまったく思いつきませんが。


[参考]

下記サンプルに出てくる CustomFontButton は、FontAwesomeを表示できるように拡張したカスタムボタンです。

こちらを参考に。

Androidで画像を使わずにオシャレなアイコンを簡単に表示する方法

※上のGIFアニメ中のボタンは CustomFontButton を更にカスタマイズしてアイコンを右寄せで表示できるようにしています。

FontAwesomeクラスはこちらを参考にしています。

https://github.com/Bearded-Hen/Android-Bootstrap/blob/master/AndroidBootstrap/src/com/beardedhen/androidbootstrap/FontAwesome.java


SampleActivity.javaの抜粋


private Handler mHandler = new Handler();
private ScheduledExecutorService mScheduledExecutor;
private ScheduledFuture<?> mScheduledFuture;
private SampleRunnable mSampleRunnable;
private Map<String, String> mFaMap = FontAwesome.getFaMap();

/**
* onClickListenerの中身
*/

private void doOnBtnClick(final View view) {

if (playing) {
// 再生中なら停止。
mScheduledFuture.cancel(true);

} else {
// 停止中なら再生開始。

/**
* newSingleThreadScheduledExecutor()を使うなり、
* 適宜変更してください。
*/

mScheduledExecutor = Executors.newScheduledThreadPool(2);

/*
* 繰り返し実行したい処理を実装するRunnnable。
* ここではアイコンの切り替え。
* このサンプルではインナークラスとして実装。
*/

mSampleRunnable = new SampleRunnable(view);

/**
* 第一引数: 繰り返し実行したい処理
* 第二引数: 指定時間後に第一引数の処理を開始
* 第三引数: 第一引数の処理完了後、指定時間後に再実行
* 第四引数: 第二、第三引数の単位
*
* mSampleRunnableをすぐに(0秒後に)実行し、完了後200ミリ秒ごとに繰り返す。
*/

mScheduledFuture = mScheduledExecutor.scheduleWithFixedDelay(mSampleRunnable, 0, 200, TimeUnit.MILLISECONDS);
}
}

class mSampleRunnable implements Runnable {

private CustomFontButton mClickedButton;

public mSampleRunnable(CustomFontButton button) {
this.mClickedButton = button;
}

@Override
public void run() {

/**
* Handlerを介してUIスレッドを更新する(postする)
*/

mHandler.post(new Runnable() {
public void run() {

/**
* 現時点のアイコン(FontAwesomeのフォント)に応じて
* 次に表示するアイコンを決める。
*/

String now = mClickedButton.getIcon();
String next;

if (now.equals(mFaMap.get("fa-volume-off"))) {
next = mFaMap.get("fa-volume-down");
} else if (now.contains(mFaMap.get("fa-volume-down"))) {
next = mFaMap.get("fa-volume-up");
} else if (now.contains(mFaMap.get("fa-volume-up"))) {
next = mFaMap.get("fa-volume-off");
} else {
next = mFaMap.get("fa-volume-off");
}
mClickedButton.setRightIcon(next);
}
});
}
}


実装の都合でメンバ変数が多くなっていますが、そこは必要に応じて修正してください。