質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.91%

ドラッグアンドドロップ

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,379

yuka3846

score 12

ドラッグアンドドロップすることで数字を入れ替えるシステムを作りたいと考えています。
この状態では指が触れたマス目が色が付き、ランダムでマス目が振動するものです。
これを改良して(おそらくonTouchEventのところでしょうか?)数字が入れ替わる仕組みの作り方を教えていただけますでしょうか。
java初心者なので全然わかりません。アルゴリズム等アドバイスいただけたらと思います。よろしくお願いします。

package com.example.admin.a0116myapplication;

import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Vibrator;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

import org.w3c.dom.Text;

import java.util.Random;

public class MainActivity extends AppCompatActivity {

    int COL=4;
    int ROW=4;
    int ON_VIB_NUM=4;
    int viewId[] = new int[COL*ROW+1];

    /* vibがオンの番号 */
    int onVib[] = new int[ON_VIB_NUM];

    //最後にタッチしたViewの列番号と行番号を保持
    private int fromRow = -1;
    private int fromCol = -1;
    private int fromId = -1;

    //現在タッチしたViewに書いてある番号を保持
    private int toRow = -1;
    private int toCol = -1;
    private int toId = -1;

    MainActivity(){
        Random rand = new Random();
        for(int i = 0; i<3; i++){
            onVib[i] = rand.nextInt(16)+1;

            int x = onVib[i];
            for(i = 0; i<16; i++){
                if(onVib[i]==x)
                    break;
            }
        }
    }

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

        /*端末の画面の幅を取得*/
        WindowManager wm = (WindowManager)getSystemService(WINDOW_SERVICE);
        Display disp = wm.getDefaultDisplay();
        Point size = new Point();
        disp.getSize(size);
        int mainWidth = size.x;

        /* ROW*COLテンキーの外枠のインスタンス*/
        TableLayout tenKey = (TableLayout) findViewById(R.id.ten_key);
        for(int numCol=0;numCol<COL;numCol++){
            /* テンキーの行部分のインスタンス*/
            TableRow tableRow = new TableRow(this);
            for(int numRow=1;numRow<ROW+1;numRow++){
                /* テンキーの要素のインスタンスの生成と番号付け */
                TextView tenKeyTextView = (TextView) getLayoutInflater().inflate(R.layout.ten_key_button,null);
                tenKeyTextView.setText(String.valueOf(numCol*COL+numRow));

                /* テンキー要素にIDを付与 */
                viewId[numCol*COL+numRow] = tenKeyTextView.generateViewId();
                tenKeyTextView.setId(viewId[numCol*COL+numRow]);

                /* 画面幅よりテンキーの要素ごとの大きさを設定 */
                tenKeyTextView.setWidth((int)((float)mainWidth/(float)(COL+0.5)));
                tenKeyTextView.setHeight((int)((float)mainWidth/(float)(ROW+0.5)));
                tenKeyTextView.setGravity(Gravity.CENTER);

                /* テンキーの要素を行部分に入れる*/
                tableRow.addView(tenKeyTextView);
            }
            /* テンキーの行部分をテンキーの枠に入れる */
            tenKey.addView(tableRow);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        for(int numCol=0;numCol<COL;numCol++) {
            for(int numRow = 1; numRow < ROW + 1; numRow++) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN: {

                        if(inViewBounds(findViewById(viewId[numCol*COL+numRow]), (int)event.getX(), (int)event.getY())){

                            //今タッチした所
                            fromCol = numCol+1;
                            fromRow = numRow+0;
                            fromId =viewId[numCol*COL+numRow];
//                            Log.d("fromId", String.valueOf(fromId));
                        }

                    }
                    case MotionEvent.ACTION_MOVE:{

                        View fromView;
                        View toView;

                        if(inViewBounds(findViewById(viewId[numCol*COL+numRow]), (int)event.getX(), (int)event.getY())){

                            toCol = numCol+1;
                            toRow = numRow+0;
                            toId = viewId[numCol*COL+numRow];
//                            Log.d("toId", String.valueOf(viewId[numCol*COL+numRow]));

                            fromView = findViewById(fromId);
                            toView = findViewById(toId);

                            //隣のマス目にまたいだら入れ替え処理
                            if(fromId != toId){

                            }

                        }
                    }
                }
            }
        }

        //各フィールド変数を更新
//        fromRow = // //;
//        fromCol = // //;
//        fromId =  // //;
//
        return true;
    }

    /* view内に(x,y)が存在するか */
    private boolean inViewBounds(final View view, int x, int y){
        Rect outRect = new Rect();
        view.getDrawingRect(outRect);
        int[] location = new int[2];
        view.getLocationOnScreen(location);
        outRect.offset(location[0], location[1]);
        //Log.d("TouchEvsyent", "X:" + location[0] + ",Y:" + location[0]);
        return outRect.contains(x, y);
    }

    private void randOnVib(){
        boolean duplicate=false;
        Random rnd = new Random();
        for(int i=0;i<ON_VIB_NUM;i++) {
            while(true) {
                onVib[i] = rnd.nextInt(COL * ROW) + 1;
                for (int j=0;j<i;j++) {
                    if (onVib[i] == onVib[j]) {
                        duplicate = true;
                    }
                }
                if (!duplicate) {
                    break;
                }
            }
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:id="@+id/main"
    tools:context="com.example.admin.a0116myapplication.MainActivity">

    <TextView
        android:id="@+id/textview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="start"/>

    <Button
        android:id="@+id/vibAnsButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="ok"
        android:layout_below="@+id/text"
        android:layout_alignParentStart="true" />

    <TableLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/vibAnsButton"
        android:id="@+id/ten_key">


    </TableLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >
</TableLayout>
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="0dp"
    >

</TextView>
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • yona

    2017/01/17 15:12

    コード用の記述に修正してください。

    キャンセル

  • yuka3846

    2017/01/17 15:46

    ご指摘ありがとうございます。一番上からMainactivity.java、activity_main.xml、ten_key.xml、ten_key_button.xmlです。アドバイス頂けたら幸いです。よろしくお願い致します。

    キャンセル

回答 1

checkベストアンサー

0

・最後にタッチしたViewの列番号と行番号を保持するフィールド変数を追加する。
・最後にタッチしたViewに書いてある番号を保持するフィールド変数を追加する。
・onTouchEventで今タッチしている列番号と行番号と最後にタッチした列番号と行番号を比較し、異なる場合は今タッチしているViewに最後にタッチしたViewの番号を入れ替え処理を行う。
・onTouchEventの最後に各フィールド変数を更新する。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/01/31 18:16

    しばらくの間色々なアドバイスありがとうございました。
    あの後色々と調べながら聞きながら取り組んだ結果無事に完成させることができました。
    色々と失礼な質問や不快な気分にさせてしまったことについて申し訳なく思います。
    本当にたくさんのアドバイスをありがとうございました。

    キャンセル

  • 2017/01/31 18:35

    力になれずごめんなさい。

    キャンセル

  • 2017/01/31 19:19

    とんでもないです!!yona様からのアドバイスが無ければ手も足も出せない状態でした。本当に感謝しています。ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.91%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る