13
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

マテリアルデザインのFAB(Floating Action Button)のアニメーションをパクる

Last updated at Posted at 2016-05-31

この記事はAndroidアプリケーション(Java)開発向け記事です。

アニメーションをしているコードだけをみたいかたは"FABのshowアニメーションのみをパクる"へどうぞ。

2016年5月現在のMaterial Designについて(雑に)

上記記事にあるように、もうすでにマテリアルデザインを導入したアプリは100万を超えたらしいです。
今後は似たようなUIが多くなり、アプリの個性が薄くなってしまう問題にぶち当たる事もあるかもしれないです。そういう場合は成功例を見て差別化をどのようにやっているのかを、研究してみるのがいいかもしれませんね。

そういうわけで差別化として「MaterialDesignなアニメーションを使ったインタラクションを入れたい!」って人向けの記事になりますかね。

一番簡単にMaterialDesignなアニメーションを確認する方法

下記のリンクにあるFABアニメーションが今回のターゲットです。
アニメーション動画へのリンク

1、とりあえず試したい場合は適当にプロジェクトを作成(minSdkVersion 14(Android 4.0以上))。
Activityをメニューから
"File -> New -> Activity -> Scrolling Activity"
でMainActivityの遷移先のActivityを作成します。ここでは名前を仮にSubActivityとしておきます。
(勝手にサポートライブラリーのdependenciesが追加されるので、そこらへんは気にしなくていいと思います。)

そうすると自動的にToolbarとFABが配置されたレイアウトが作成され、SubActivityクラスでは、スクロールする中身の実装やToolbarのカスタマイズなどをすればいいだけの状態のActivityが作成されます。

2、次はSubActivityのFABに遷移したときに動くアニメーションを入れたいと思います。
ここで、一々ゴリゴリAnimationを定義する必要はなく、FloatingActionButtonクラスにshow()というメソッドが定義されているので、そちらを呼び出せばいいです。(onResumeでshowしてもアニメーションしないので注意)

コードとしてはonCreateでFABをfindViewByIdしている次の行から以下のコードを書きます。

SubActivity.java
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sub);
        final FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fab);
        // VISBLE以外の状態を設定する
        fab.setVisibility(View.GONE);
        fab.getViewTreeObserver()
           .addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                fab.show();
            }
        });
    }

注意点はshowする際はfabは可視(View.VISIBLE)の状態ではいけません。showされる前のFABのVisibilityはGONEかINVISIBLEにする必要があります。

これだけで、画面遷移した際にFABがひょこっと出てくるようになります。

FABのshow時のアニメーションについて

show()のメソッド定義を見てもらえばわかりますけど、show()メソッド無いにアニメーションが直書きされています。こんな感じ↓。

FloatingActionButtonIcs.java(android.support.design.widget)
 @Override
    void show(@Nullable final InternalVisibilityChangedListener listener, final boolean fromUser) {
        if (mIsHiding || mView.getVisibility() != View.VISIBLE) {
            if (ViewCompat.isLaidOut(mView) && !mView.isInEditMode()) {
                mView.animate().cancel();
                if (mView.getVisibility() != View.VISIBLE) {
                    // If the view isn't visible currently, we'll animate it from a single pixel
                    mView.setAlpha(0f);
                    mView.setScaleY(0f);
                    mView.setScaleX(0f);
                }
                mView.animate()
                        .scaleX(1f)
                        .scaleY(1f)
                        .alpha(1f)
                        .setDuration(SHOW_HIDE_ANIM_DURATION)
                        .setInterpolator(AnimationUtils.LINEAR_OUT_SLOW_IN_INTERPOLATOR)
                        .setListener(new AnimatorListenerAdapter() {
                            @Override
                            public void onAnimationStart(Animator animation) {
                                mView.internalSetVisibility(View.VISIBLE, fromUser);
                            }

                            @Override
                            public void onAnimationEnd(Animator animation) {
                                if (listener != null) {
                                    listener.onShown();
                                }
                            }
                        });
            } else {
                mView.internalSetVisibility(View.VISIBLE, fromUser);
                mView.setAlpha(1f);
                mView.setScaleY(1f);
                mView.setScaleX(1f);
                if (listener != null) {
                    listener.onShown();
                }
            }
        }
    }

再利用できませんよね…。ケチ。

FABのshowアニメーションのみをパクる

くどくど長くなってすみません、本題はこちらです。
上のコードそのまま使うのもいいんですけど、show()と同じに非表示にするときにhide()というメソッドもあるし、まぁ表示するアニメーションだけ欲しいし、全部書くのは面倒かなと思いますので、今回は最小限のパクリに抑えようと思います。

パクった結果が下記のコードです。

AnimationUtil.java

    /** view animation defines **/
    public interface InternalVisibilityChangedListener {
        void onShown();
    }
    private static final int SHOW_HIDE_ANIM_DURATION = 200;
    private static final Interpolator LINEAR_OUT_SLOW_IN_INTERPOLATOR =
            new LinearOutSlowInInterpolator();

    public static void show(final View view, final InternalVisibilityChangedListener listener) {
        if (view.getVisibility() == View.VISIBLE) return;

        view.animate().cancel();

        view.setAlpha(0f);
        view.setScaleY(0f);
        view.setScaleX(0f);

        view.animate()
            .scaleX(1f)
            .scaleY(1f)
            .alpha(1f)
            .setDuration(SHOW_HIDE_ANIM_DURATION)
            .setInterpolator(LINEAR_OUT_SLOW_IN_INTERPOLATOR)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationStart(Animator animation) {
                    view.setVisibility(View.VISIBLE);
                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    if(listener!= null) listener.onShown();
                    super.onAnimationEnd(animation);
                }
            });

    }

これで、他のViewでも同様にひょこっとスケールしてくるアニメーションを表現できるようになりました。

皆さまのお手伝いになれば光栄です。

以上が今回の記事の内容になります。

13
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?