Android-drag-and-drop

提供:Dev Guides
移動先:案内検索

Android-ドラッグアンドドロップ

Androidのドラッグ/ドロップフレームワークを使用すると、ユーザーは、グラフィカルなドラッグアンドドロップジェスチャを使用して、現在のレイアウトのあるビューから別のビューにデータを移動できます。 API 11 現在、他のビューまたはビューグループへのビューのドラッグアンドドロップがサポートされています。フレームワークには、ドラッグアンドドロップ機能をサポートする次の3つの重要なコンポーネントが含まれています-

  • イベントクラスをドラッグ
  • リスナーをドラッグ
  • ヘルパーメソッドとクラス

ドラッグ/ドロッププロセス

ドラッグアンドドロッププロセスには基本的に4つのステップまたは状態があります-

  • Started -このイベントは、レイアウト内のアイテムのドラッグを開始すると発生します。アプリケーションは、_startDrag()_メソッドを呼び出して、システムにドラッグの開始を指示します。 startDrag()メソッド内の引数は、ドラッグされるデータ、このデータのメタデータ、およびドラッグシャドウを描画するためのコールバックを提供します。 +システムは最初にアプリケーションにコールバックして、ドラッグシャドウを取得します。 次に、デバイスにドラッグシャドウを表示します。 +次に、システムは、現在のレイアウトのすべてのViewオブジェクトの登録済みドラッグイベントリスナーに、アクションタイプ_ACTION_DRAG_STARTED_のドラッグイベントを送信します。 +可能なドロップイベントを含むドラッグイベントの受信を継続するには、ドラッグイベントリスナーは true を返す必要があります。ドラッグイベントリスナーがfalseを返す場合、システムがドラッグイベントを送信するまで現在の操作のドラッグイベントを受信しませんアクションタイプがACTION_DRAG_ENDEDの場合。
  • Continuing -ユーザーはドラッグを続けます。 システムは、ACTION_DRAG_ENTEREDアクションに続いてACTION_DRAG_LOCATIONアクションを、ドラッグポイントが入るビューの登録済みドラッグイベントリスナーに送信します。 リスナーは、イベントに応じてViewオブジェクトの外観を変更するか、Viewを強調表示して反応させることができます。 +ドラッグイベントリスナーは、ユーザーがビューの境界ボックスの外側にドラッグシャドウを移動した後、ACTION_DRAG_EXITEDアクションを受け取ります。
  • ドロップ-ユーザーはビューの境界ボックス内でドラッグされたアイテムを離します。 システムは、ViewオブジェクトのリスナーにアクションタイプACTION_DROPのドラッグイベントを送信します。
  • 終了-アクションタイプACTION_DROPの直後に、システムはアクションタイプACTION_DRAG_ENDEDのドラッグイベントを送信して、ドラッグ操作が終了したことを示します。

DragEventクラス

*DragEvent* は、ドラッグアンドドロップ操作中のさまざまな時点でシステムによって送信されるイベントを表します。 このクラスは、ドラッグ/ドロッププロセス中に使用するいくつかの定数と重要なメソッドを提供します。

定数

以下は、DragEventクラスの一部として使用可能なすべての定数整数です。

Sr.No. Constants & Description
1

ACTION_DRAG_STARTED

ドラッグアンドドロップ操作の開始を通知します。

2

ACTION_DRAG_ENTERED

ドラッグポイントがビューの境界ボックスに入ったことをビューに通知します。

3

ACTION_DRAG_LOCATION

ドラッグシャドウがビューオブジェクトの境界ボックス内にある場合、ACTION_DRAG_ENTEREDの後にビューに送信されます。

4

ACTION_DRAG_EXITED

ユーザーがビューの境界ボックスの外側にドラッグシャドウを移動したことを通知します。

5

ACTION_DROP

ユーザーがドラッグシャドウをリリースしたことをビューに通知し、ドラッグポイントはビューの境界ボックス内にあります。

6

ACTION_DRAG_ENDED

ドラッグアンドドロップ操作が完了したことをビューに通知します。

方法

以下は、DragEventクラスの一部として使用できる重要で最も頻繁に使用されるいくつかのメソッドです。

Sr.No. Constants & Description
1

int getAction()

このイベントのアクション値を調べます。

2

ClipData getClipData()

startDrag()の呼び出しの一部としてシステムに送信されたClipDataオブジェクトを返します。

3

ClipDescription getClipDescription()

ClipDataに含まれるClipDescriptionオブジェクトを返します。

4

boolean getResult()

ドラッグアンドドロップ操作の結果の表示を返します。

5

float getX()

ドラッグポイントのX座標を取得します。

6

float getY()

ドラッグポイントのY座標を取得します。

7

String toString()

このDragEventオブジェクトの文字列表現を返します。

ドラッグイベントのリッスン

レイアウト内のビューのいずれかがDragイベントに応答するようにする場合、ビューは View.OnDragListener またはsetup * onDragEvent(DragEvent)*コールバックメソッドを実装します。 システムがメソッドまたはリスナーを呼び出すと、上記のDragEventオブジェクトが渡されます。 Viewオブジェクトのリスナーとコールバックメソッドの両方を持つことができます。 この場合、システムはまずリスナーを呼び出し、リスナーがtrueを返す限りコールバックを定義します。

_onDragEvent(DragEvent)_メソッドと_View.OnDragListener_の組み合わせは、Androidの古いバージョンのタッチイベントで使用される* onTouchEvent()と *View.OnTouchListener の組み合わせに類似しています。

ドラッグイベントの開始

移動するデータの ClipData および ClipData.Item を作成することから始めます。 _ClipData_オブジェクトの一部として、ClipData内の ClipDescription オブジェクトに保存されているメタデータを提供します。 データの移動を表さないドラッグアンドドロップ操作の場合、実際のオブジェクトの代わりに null を使用できます。

次に、拡張 View.DragShadowBuilder を拡張して、ビューをドラッグするためのドラッグシャドウを作成するか、単に_View.DragShadowBuilder(View)_を使用して、渡されたビュー引数と同じサイズのデフォルトのドラッグシャドウを作成します。ドラッグシャドウの中心にタッチポイントがあります。

次の例は、* View.setOnLongClickListener()View.setOnTouchListener()、および View.OnDragEventListener()*を使用した単純なドラッグアンドドロップの機能を示しています。

Step Description
1 You will use Android studio IDE to create an Android application and name it as My Application under a package com.example.saira_000.myapplication.
2 Modify src/MainActivity.java file and add the code to define event listeners as well as a call back methods for the logo image used in the example.
3 Copy image abc.png in res/drawable-* folders. You can use images with different resolution in case you want to provide them for different devices.
4 Modify layout XML file res/layout/activity_main.xml to define default view of the logo images.
5 Run the application to launch Android emulator and verify the result of the changes done in the application.

以下は、変更されたメインアクティビティファイル src/MainActivity.java の内容です。 このファイルには、基本的な各ライフサイクルメソッドを含めることができます。

package com.example.saira_000.myapplication;

import android.app.Activity;

import android.content.ClipData;
import android.content.ClipDescription;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;

import android.view.DragEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;

import android.widget.ImageView;
import android.widget.RelativeLayout;


public class MainActivity extends Activity {
   ImageView img;
   String msg;
   private android.widget.RelativeLayout.LayoutParams layoutParams;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      img=(ImageView)findViewById(R.id.imageView);

      img.setOnLongClickListener(new View.OnLongClickListener() {
         @Override
         public boolean onLongClick(View v) {
            ClipData.Item item = new ClipData.Item((CharSequence)v.getTag());
            String[] mimeTypes = {ClipDescription.MIMETYPE_TEXT_PLAIN};

            ClipData dragData = new ClipData(v.getTag().toString(),mimeTypes, item);
            View.DragShadowBuilder myShadow = new View.DragShadowBuilder(img);

            v.startDrag(dragData,myShadow,null,0);
            return true;
         }
      });

      img.setOnDragListener(new View.OnDragListener() {
         @Override
         public boolean onDrag(View v, DragEvent event) {
            switch(event.getAction()) {
               case DragEvent.ACTION_DRAG_STARTED:
               layoutParams = (RelativeLayout.LayoutParams)v.getLayoutParams();
               Log.d(msg, "Action is DragEvent.ACTION_DRAG_STARTED");

              //Do nothing
               break;

               case DragEvent.ACTION_DRAG_ENTERED:
               Log.d(msg, "Action is DragEvent.ACTION_DRAG_ENTERED");
               int x_cord = (int) event.getX();
               int y_cord = (int) event.getY();
               break;

               case DragEvent.ACTION_DRAG_EXITED :
               Log.d(msg, "Action is DragEvent.ACTION_DRAG_EXITED");
               x_cord = (int) event.getX();
               y_cord = (int) event.getY();
               layoutParams.leftMargin = x_cord;
               layoutParams.topMargin = y_cord;
               v.setLayoutParams(layoutParams);
               break;

               case DragEvent.ACTION_DRAG_LOCATION  :
               Log.d(msg, "Action is DragEvent.ACTION_DRAG_LOCATION");
               x_cord = (int) event.getX();
               y_cord = (int) event.getY();
               break;

               case DragEvent.ACTION_DRAG_ENDED   :
               Log.d(msg, "Action is DragEvent.ACTION_DRAG_ENDED");

              //Do nothing
               break;

               case DragEvent.ACTION_DROP:
               Log.d(msg, "ACTION_DROP event");

              //Do nothing
               break;
               default: break;
            }
            return true;
         }
      });

      img.setOnTouchListener(new View.OnTouchListener() {
         @Override
         public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
               ClipData data = ClipData.newPlainText("", "");
               View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(img);

               img.startDrag(data, shadowBuilder, img, 0);
               img.setVisibility(View.INVISIBLE);
               return true;
            } else {
               return false;
            }
         }
      });
   }
}

以下は res/layout/activity_main.xml ファイルの内容です-

'_次のコードで、abcはfinddevguides.comのロゴを示します_

<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:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   android:paddingBottom="@dimen/activity_vertical_margin"
   tools:context=".MainActivity">

   <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Drag and Drop Example"
      android:id="@+id/textView"
      android:layout_alignParentTop="true"
      android:layout_centerHorizontal="true"
      android:textSize="30dp"/>

   <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Tutorials Point"
      android:id="@+id/textView2"
      android:layout_below="@+id/textView"
      android:layout_centerHorizontal="true"
      android:textSize="30dp"
      android:textColor="#ff14be3c"/>>

   <ImageView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/imageView"
      android:src="@drawable/abc"
      android:layout_below="@+id/textView2"
      android:layout_alignRight="@+id/textView2"
      android:layout_alignEnd="@+id/textView2"
      android:layout_alignLeft="@+id/textView2"
      android:layout_alignStart="@+id/textView2"/>

</RelativeLayout>

以下は、2つの新しい定数を定義する res/values/strings.xml の内容です-

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <string name="app_name">My Application</string>
</resources>

以下は、 AndroidManifest.xml のデフォルトのコンテンツです-

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.saira_000.myapplication" >

   <application
      android:allowBackup="true"
      android:icon="@drawable/ic_launcher"
      android:label="@string/app_name"
      android:theme="@style/AppTheme" >

      <activity
         android:name=".MainActivity"
         android:label="@string/app_name" >

         <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
         </intent-filter>

      </activity>

   </application>
</manifest>
*My Application* アプリケーションを実行してみましょう。 環境設定中に *AVD* を作成したと思います。 Android Studioからアプリを実行するには、プロジェクトのアクティビティファイルの1つを開き、ツールバーの[画像を実行:/android/images/eclipse_run.jpg [Eclipse Run Icon]アイコンをクリックします。 AndroidスタジオはAVDにアプリをインストールして起動し、セットアップとアプリケーションで問題がなければ、次のエミュレータウィンドウが表示されます-

Androidのドラッグアンドドロップ

表示されたfinddevguidesロゴを長押しすると、ロゴの画像がその場所から1秒間長押しすると少し移動します。画像のドラッグを開始するタイミングです。 画面上でドラッグして、新しい場所にドロップできます。

Android Drop to New Location