Androidアプリ開発

フローティングアイコンのアニメーション

この記事は約15分で読めます。
記事内に広告が含まれています。
スポンサーリンク

この記事はAndroidスマホ用のアプリ開発の中で、
今後の開発で再使用性が高いと思われるコーディングをまとめたものです。
Javaの開発経験、XML構文規則、Androidのアプリ開発経験がある方を対象としています。
Androidのアプリ開発でお役にたててれば、嬉しいです。
(これからAndroidのアプリ開発やJavaでの開発を始めたい方への案内は、
記事の最後で紹介します)

この記事のテーマ


フローティングアイコンをアニメーション表示する

かなりお買い得な360°カメラです。

ポイント

録画中と一時停止など、フローティングアイコンのアニメーション表示の切り替えの実装方法を紹介します。

他のアプリ画面の上に重ねてフローティングアイコンを表示する

フローティングアイコン

フローティングアイコン(ImageView)をWindowManagerで表示します。
フローティングアイコンはスワイプで移動、タップ操作できるようにTouchListenerを設定します。

    private class FloatingButton {
        android.view.WindowManager windowManager;
        WindowManager.LayoutParams layoutParams;
        AnimationDrawable drawable;
        View.OnTouchListener onTouchListener;
        ImageView imageView;
        Position initial = new Position(0, 0);
        @SuppressLint("ClickableViewAccessibility")
        private FloatingButton(Context context, OnClickListener onClickListener) {
            DisplayMetrics displayMetrics =  context.getResources().getDisplayMetrics();
            windowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
            imageView = new ImageView(context);
            imageView.setBackgroundResource(R.drawable.ic_stop);
            layoutParams = new WindowManager.LayoutParams(
                    (int) (64 * displayMetrics.density),
                    (int) (64 * displayMetrics.density),
                    android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
                    android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                    PixelFormat.TRANSLUCENT);
            layoutParams.gravity = Gravity.TOP | Gravity.START;
            layoutParams.x = 0;
            layoutParams.y = 0;
            onTouchListener = new View.OnTouchListener() {
                final int  MAX_CLICK_DURATION = 300;
                long time = 0;
                @SuppressLint("ClickableViewAccessibility")
                @Override
                public boolean onTouch(View view, android.view.MotionEvent motionEvent) {
                    switch (motionEvent.getAction()) {
                        case ACTION_DOWN:
                                initial.fx = layoutParams.x - motionEvent.getRawX();
                                initial.fy = layoutParams.y - motionEvent.getRawY();
                            time = System.currentTimeMillis();
                            break;
                        case ACTION_MOVE:
                                if (initial != null) {
                                    layoutParams.x = (int) (initial.fx + motionEvent.getRawX());
                                    layoutParams.y = (int) (initial.fy + motionEvent.getRawY());
                                    windowManager.updateViewLayout(view, layoutParams);
                                }
                                break;
                        case ACTION_UP:
                            time = System.currentTimeMillis() - time;
                            if (time < MAX_CLICK_DURATION) {
                                time = System.currentTimeMillis();
                                taps++;
                                new Handler(Looper.getMainLooper()).postDelayed(() -> {
                                    if (taps == 1) {
                                        onClickListener.onClick();
                                    } else if (taps == 2) {
                                        onClickListener.onDoubleClick();
                                    }
                                    taps = 0;
                                }, MAX_CLICK_DURATION);
                            }
                            break;
                    }
                    return true;
                }
            };
            imageView.setOnTouchListener(onTouchListener);
         }
        private void visible(Boolean visible) {
            if (imageView != null) {
                if (visible) {
                    windowManager.addView(imageView, layoutParams);
                } else {
                    if (imageView.getWindowToken() != null){
                        windowManager.removeView(imageView);
                    }
                }
            }
        }
        @SuppressLint("ClickableViewAccessibility")
        private void recoding(boolean on) {
            if (imageView != null) {
                if (imageView.getWindowToken() != null){
                    windowManager.removeView(imageView);
                }
                imageView = new ImageView(context);
                if (on) {
                    imageView.setBackgroundResource(R.drawable.ic_rec);
                    drawable = (AnimationDrawable) imageView.getBackground();
                    drawable.start();
                } else {
                    imageView.setBackgroundResource(R.drawable.ic_stop);
                }
                imageView.setOnTouchListener(onTouchListener);
                windowManager.addView(imageView, layoutParams);
            }
        }
    }
    private interface OnClickListener {
        void onClick();
        void onDoubleClick();
    }
    private static class Position {
        float    fx, fy;
        int      ix, iy;
        Position(float x, float y) {
            fx = x;
            fy = y;
            ix = (int) x;
            iy = (int) y;
        }
    }

タップとダブルタップはMAX_CLICK_DURATION(300ミリ秒)のタップ数で判定します。
フローティングアイコンのアニメーション表示はanimation-listに定義します。
録画中は複数のイメージをアニメーション定義(ic_rec.xml)します。
フローティングアイコンの表示切り替えですが、onTouchで切り替えできますが、インタフェース(OnClickListener)から操作する場合、ImageViewを再生成する必要があります。

ic_rec.xml

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    <item android:drawable="@drawable/ic_rec1" android:duration="250" />
    <item android:drawable="@drawable/ic_rec2" android:duration="200" />
    <item android:drawable="@drawable/ic_rec3" android:duration="200" />
    <item android:drawable="@drawable/ic_rec4" android:duration="400" />
    <item android:drawable="@drawable/ic_rec3" android:duration="200" />
    <item android:drawable="@drawable/ic_rec2" android:duration="200" />
    <item android:drawable="@drawable/ic_rec1" android:duration="250" />
</animation-list>

ic_rec1 ~ ic_rec4 はアイコンのアニメーションの1コマ。

インタフェース(OnClickListener)から、フローティングアイコンの表示を切り替えます。

    private boolean recording = false; 
    :
    FloatingButton floatingButton = new FloatingButton(getApplicationContext, new OnClickListener() {
         @Override
         public void onClick() {
             // フローティングアイコンをタップした時の処理
             if (recording) {
                 // 一時停止中のフローティングアイコン
                 recording = false;
                 floatingButton.recoding(false);
                 :
             } else {
                 // 録画中のフローティングアイコン
                 recording = true;
                 floatingButton.recoding(true);
             }  
         }
         @Override
         public void onDoubleClick() {
             // フローティングアイコンをダブルタップした時の処理
             :
         }
     });
     floatingButton.visible(true);

今回は、ここまでです。

フローティングアイコンのアニメーション表示を切り替えているAndroidアプリです。

誤字脱字、意味不明でわかりづらい、
もっと詳しく知りたいなどのご意見は、
このページの最後にある
コメントか、
こちらから、お願いいたします♪

ポチッとして頂けると、
次のコンテンツを作成する励みになります♪

ブログランキング・にほんブログ村へ

これからAndroidのアプリ開発やJavaでの開発を始めたい方へ

アプリケーション開発経験がない方や、アプリケーション開発経験がある方でも、JavaやC#などのオブジェクト指向言語が初めての方は、Androidのアプリ開発ができるようになるには、かなりの時間がかかります。
オンラインスクールでの習得を、強くおススメします。

未経験者からプログラマーを目指すのに最適です。まずは無料カウンセリングから♪

ゲーム系に強いスクール、UnityやUnrealEngineを習得するのに最適です。まずは無料オンライン相談から♪

参考になったら、💛をポッチとしてね♪

スポンサーリンク
シェアする
msakiをフォローする
スポンサーリンク

コメント欄

タイトルとURLをコピーしました