Androidアプリ開発

ドラッグ&ドロップで移動可能なViewGroup

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

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

この記事のテーマ


ドラッグ&ドロップで移動可能なViewGroupを実装する

大容量のスマホ本体を買うより、SDカードで容量を増やす方法の方が断然お得です。

ポイント

操作パネルなど、フリーレイアウトで自由に移動できるViewGroupの実装を紹介します。
ポイントはlayoutを使用することで移動は可能ですが、再描画の際に元の位置に戻る問題が発生します。
これは、親のViewGroupが子ViewGroupまたは、Viewの位置を確定させているためです。

ViewGroup

ViewGroupの移動と再描画

ViewGroupTextView(title)にTouchListenerを設定して、motionEventでドラッグ&ドロップを実装します。
RelativeLayout(panel)は、motionEventで位置を取得し、layoutで移動します。
また、画面からはみでない制御とロングタップで移動可能にする制御します。

    private RelativeLayout[]        panel;
    private TextView[]              title;
    private long[]                  isMove;
    private int[][]                 layout;
    private int[][]                 xy;
    private boolean[]               move;
    :

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_home, container, false);
        RelativeLayout main = view.findViewById(R.id.main);
        main.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
            :
            if (layout[0][0] >= 0 && layout[0][1] >= 0) {
                panel[0].layout(layout[0][0], layout[0][1], layout[0][0] + panel[0].getWidth(), layout[0][1] + panel[0].getHeight());
            }
            panel[0].setVisibility(View.VISIBLE);
            :
        });
        :
        // パネル表示
        layout = new int[4][2];
        xy = new int[4][4];
        move = new boolean[4];
        isMove = new long[4];
        panel = new RelativeLayout[]{view.findViewById(R.id.log1), view.findViewById(R.id.log2), view.findViewById(R.id.log3), view.findViewById(R.id.log4)};
        title = new TextView[]{view.findViewById(R.id.title1), view.findViewById(R.id.title2), view.findViewById(R.id.title3), view.findViewById(R.id.title4)};
        :
        return view;
    }

    public void counter(int index, int[] xy, RelativeLayout panel, TextView title, NumberPicker picker, TextView textView, TextView shadow, float value) {
        :
        title.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, android.view.MotionEvent motionEvent) {
                xy[0] = Math.max((int) motionEvent.getRawX(), panel.getWidth() / 2);
                xy[0] = Math.min(xy[0], mainActivity.displayMetrics.widthPixels - panel.getWidth() / 2);
                xy[1] = Math.max((int) motionEvent.getRawY(), panel.getHeight() / 2);
                xy[1] = Math.min(xy[1], mainActivity.displayMetrics.heightPixels - panel.getHeight() / 2);
                switch (motionEvent.getAction()) {
                    case ACTION_MOVE:
                        if (move[index] && isMove[index] > System.currentTimeMillis()) {
                            if (panel.getLeft() + (xy[0] - xy[2]) >= 0 && panel.getTop() + (xy[1] - xy[3]) >= 0) {
                                layout[index] = new int[]{panel.getLeft() + (xy[0] - xy[2]), panel.getTop() + (xy[1] - xy[3])};
                                panel.layout(layout[index][0], layout[index][1], layout[index][0] + panel.getWidth(), layout[index][1] + panel.getHeight());
                                isMove[index] = System.currentTimeMillis() + 1000;
                            }
                        }
                        break;
                    case MotionEvent.ACTION_DOWN:
                        panel.setAlpha(0.5f);
                        move[index] = true;
                        break;
                    default:
                        if (layout != null && isMove[index] > System.currentTimeMillis()) {
                            if (layout[index][0] < 0) {
                                layout[index][0] = 0;
                            } else if (layout[0][0] > mainActivity.frame.getWidth() - panel.getWidth()) {
                                layout[index][0] = mainActivity.frame.getWidth() - panel.getWidth();
                            }
                            if (layout[index][1] < 0) {
                                layout[index][1] = 0;
                            } else if (layout[index][1] > mainActivity.frame.getHeight() - panel.getHeight()) {
                                layout[index][1] = mainActivity.frame.getHeight() - panel.getHeight();
                            }
                            panel.layout(layout[index][0], layout[index][1], layout[index][0] + panel.getWidth(), layout[index][1] + panel.getHeight());
                        }
                        panel.setAlpha(1);
                        move[index] = false;
                        break;
                }
                xy[2] = xy[0];
                xy[3] = xy[1];
                return false;
            }
        });
        title.setOnLongClickListener(view -> {
            // 3秒間移動可能
            isMove[index] = System.currentTimeMillis() + 3000;
            return false;
        });
        :
    }
}

移動できるRelativeLayout(panel)が複数あるため、各変数は配列で管理します。
再描画の際に元の位置に戻る問題ですが、親のRelativeLayout(main)のGlobalLayoutListenerRelativeLayout(panel)をlayoutで移動します。

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <RelativeLayout
        android:id="@+id/main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:ignore="UselessParent">
        :
        <RelativeLayout
            android:id="@+id/log4"
            android:layout_width="192dp"
            android:layout_height="192dp"
            android:layout_alignParentBottom="true"
            android:layout_alignParentEnd="true"
            android:visibility="invisible">
            <TextView
                android:id="@+id/title4"
                android:layout_width="wrap_content"
                android:layout_height="60dp"
                android:layout_alignParentBottom="true"
                android:layout_centerHorizontal="true"
                android:gravity="center|top"
                android:background="?attr/selectableItemBackgroundBorderless"/>
            :
        </RelativeLayout>
        :
    </RelativeLayout>

今回は、ここまでです。

ドラッグ&ドロップで移動可能なViewGroupを実装しているAndroidアプリです。

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

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

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

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

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

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

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

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

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

コメント欄

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