Android - ลากและวาง

เฟรมเวิร์กการลาก / วางของ Android ช่วยให้ผู้ใช้ของคุณสามารถย้ายข้อมูลจากมุมมองหนึ่งไปยังอีกมุมมองหนึ่งในเค้าโครงปัจจุบันโดยใช้ท่าทางลากและวางแบบกราฟิก ณAPI 11 รองรับการลากและวางมุมมองไปยังมุมมองหรือกลุ่มมุมมองอื่น ๆ เฟรมเวิร์กประกอบด้วยองค์ประกอบที่สำคัญสามประการต่อไปนี้เพื่อรองรับฟังก์ชันการลากและวาง

  • Drag event class.

  • Drag listeners.

  • Helper methods and classes.

กระบวนการลาก / วาง

โดยทั่วไปมีสี่ขั้นตอนหรือสถานะในกระบวนการลากและวาง -

  • Started - เหตุการณ์นี้เกิดขึ้นเมื่อคุณเริ่มลากรายการในเค้าโครงแอปพลิเคชันของคุณเรียกใช้เมธอด startDrag ()เพื่อบอกให้ระบบเริ่มการลาก อาร์กิวเมนต์ภายในเมธอด startDrag () ให้ข้อมูลที่จะลากข้อมูลเมตาสำหรับข้อมูลนี้และการเรียกกลับสำหรับการวาดเงาลาก

    ระบบจะตอบกลับก่อนโดยโทรกลับไปที่แอปพลิเคชันของคุณเพื่อรับเงาลาก จากนั้นจะแสดงเงาลากบนอุปกรณ์

    จากนั้นระบบจะส่งเหตุการณ์ลากที่มีประเภทการดำเนินการACTION_DRAG_STARTEDไปยังผู้ฟังเหตุการณ์การลากที่ลงทะเบียนสำหรับวัตถุ View ทั้งหมดในเค้าโครงปัจจุบัน

    หากต้องการรับเหตุการณ์ลากต่อไปรวมถึงเหตุการณ์การดร็อปที่เป็นไปได้ผู้ฟังเหตุการณ์ลากจะต้องส่งคืน trueหาก Listener เหตุการณ์ลากส่งคืนเป็นเท็จจะไม่ได้รับเหตุการณ์การลากสำหรับการดำเนินการปัจจุบันจนกว่าระบบจะส่งเหตุการณ์ลากที่มีประเภทการดำเนินการ ACTION_DRAG_ENDED

  • Continuing- ผู้ใช้ลากต่อไป ระบบส่งการดำเนินการ ACTION_DRAG_ENTERED ตามด้วยการดำเนินการ ACTION_DRAG_LOCATION ไปยังผู้ฟังเหตุการณ์การลากที่ลงทะเบียนไว้สำหรับมุมมองที่จุดลากเข้า ผู้ฟังอาจเลือกที่จะปรับเปลี่ยนลักษณะที่ปรากฏของวัตถุ View เพื่อตอบสนองต่อเหตุการณ์หรือสามารถตอบสนองโดยการเน้นมุมมอง

    ผู้ฟังเหตุการณ์การลากได้รับการดำเนินการ ACTION_DRAG_EXITED หลังจากที่ผู้ใช้ย้ายเงาลากออกนอกกรอบขอบเขตของมุมมอง

  • Dropped- ผู้ใช้ปล่อยรายการที่ลากภายในกรอบขอบเขตของ View ระบบจะส่งเหตุการณ์การลากให้ผู้ฟังของวัตถุดูด้วยประเภทการดำเนินการ ACTION_DROP

  • Ended - หลังจากประเภทการดำเนินการ ACTION_DROP ระบบจะส่งเหตุการณ์ลากที่มีประเภทการดำเนินการ ACTION_DRAG_ENDED เพื่อระบุว่าการดำเนินการลากสิ้นสุดลงแล้ว

คลาส DragEvent

DragEventหมายถึงเหตุการณ์ที่ระบบส่งออกในช่วงเวลาต่างๆระหว่างการดำเนินการลากและวาง คลาสนี้มีค่าคงที่และวิธีการสำคัญเพียงไม่กี่อย่างที่เราใช้ในระหว่างกระบวนการลาก / วาง

ค่าคงที่

ต่อไปนี้เป็นค่าคงที่จำนวนเต็มทั้งหมดที่มีอยู่ในคลาส DragEvent

ซีเนียร์ ค่าคงที่และคำอธิบาย
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

ซีเนียร์ ค่าคงที่และคำอธิบาย
1

int getAction()

ตรวจสอบมูลค่าการกระทำของเหตุการณ์นี้ ..

2

ClipData getClipData()

ส่งคืนอ็อบเจ็กต์ ClipData ที่ส่งไปยังระบบโดยเป็นส่วนหนึ่งของการเรียกใช้ startDrag ()

3

ClipDescription getClipDescription()

ส่งคืนอ็อบเจ็กต์ ClipDescription ที่มีอยู่ใน ClipData

4

boolean getResult()

ส่งคืนการบ่งชี้ผลลัพธ์ของการดำเนินการลากและวาง

5

float getX()

รับพิกัด X ของจุดลาก

6

float getY()

รับพิกัด Y ของจุดลาก

7

String toString()

ส่งกลับการแสดงสตริงของวัตถุ DragEvent นี้

การรับฟังเหตุการณ์ลาก

หากคุณต้องการมุมมองใด ๆ ของคุณภายใน Layout ควรตอบสนองเหตุการณ์ Drag จากนั้นมุมมองของคุณก็จะดำเนินการ View.OnDragListener หรือตั้งค่า onDragEvent(DragEvent)วิธีการโทรกลับ เมื่อระบบเรียกใช้เมธอดหรือ Listener ระบบจะส่งผ่านอ็อบเจกต์ DragEvent ที่อธิบายข้างต้นไปให้พวกเขา คุณสามารถมีทั้ง Listener และวิธีการโทรกลับสำหรับ View object หากสิ่งนี้เกิดขึ้นระบบจะเรียกผู้ฟังก่อนจากนั้นจึงกำหนดการเรียกกลับตราบเท่าที่ผู้ฟังส่งคืนค่าจริง

การรวมกันของเมธอด onDragEvent (DragEvent)และView OnDragListenerนั้นคล้ายคลึงกับการรวมกันของonTouchEvent() และ View.OnTouchListener ใช้กับเหตุการณ์การสัมผัสใน Android เวอร์ชันเก่า

การเริ่มต้นเหตุการณ์การลาก

คุณเริ่มต้นด้วยการสร้างไฟล์ ClipData และ ClipData.Itemสำหรับข้อมูลที่ถูกย้าย ในฐานะที่เป็นส่วนหนึ่งของวัตถุClipDataให้จัดหาข้อมูลเมตาที่เก็บไว้ในไฟล์ClipDescriptionวัตถุภายใน ClipData สำหรับการดำเนินการลากและวางที่ไม่ได้แสดงถึงการเคลื่อนย้ายข้อมูลคุณอาจต้องการใช้null แทนที่จะเป็นวัตถุจริง

ถัดไปคุณสามารถขยายส่วนขยายได้ View.DragShadowBuilderเพื่อสร้างเงาลากสำหรับลากมุมมองหรือเพียงแค่คุณสามารถใช้View.DragShadowBuilder (View)เพื่อสร้างเงาลากเริ่มต้นที่มีขนาดเดียวกับอาร์กิวเมนต์ View ที่ส่งไปให้โดยจุดสัมผัสที่อยู่ตรงกลางของเงาลาก

ตัวอย่าง

ตัวอย่างต่อไปนี้แสดงการทำงานของการลากและวางแบบธรรมดาโดยใช้ View.setOnLongClickListener(), View.setOnTouchListener()และ View.OnDragEventListener().

ขั้นตอน คำอธิบาย
1 คุณจะใช้ Android สตูดิโอ IDE ในการสร้างแอพลิเคชัน Android และชื่อเป็นแอพลิเคชันของฉันภายใต้แพคเกจcom.example.saira_000.myapplication
2 แก้ไขไฟล์src / MainActivity.javaและเพิ่มโค้ดเพื่อกำหนดตัวฟังเหตุการณ์ตลอดจนวิธีการเรียกกลับสำหรับรูปภาพโลโก้ที่ใช้ในตัวอย่าง
3 คัดลอกรูปภาพ abc.png ในโฟลเดอร์res / drawable- * คุณสามารถใช้รูปภาพที่มีความละเอียดแตกต่างกันได้ในกรณีที่คุณต้องการจัดเตรียมให้กับอุปกรณ์ต่างๆ
4 แก้ไขไฟล์ XML เค้าโครงres / layout / activity_main.xmlเพื่อกำหนดมุมมองเริ่มต้นของภาพโลโก้
5 เรียกใช้แอปพลิเคชันเพื่อเปิดโปรแกรมจำลอง Android และตรวจสอบผลลัพธ์ของการเปลี่ยนแปลงที่ทำในแอปพลิเคชัน

ต่อไปนี้เป็นเนื้อหาของไฟล์กิจกรรมหลักที่แก้ไข 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 ระบุโลโก้ของ tutorialspoint.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>

ต่อไปนี้จะเป็นเนื้อหาของ 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 ให้เปิดไฟล์กิจกรรมของโครงการแล้วคลิก

ไอคอนเรียกใช้จากแถบเครื่องมือ Android studio ติดตั้งแอปบน AVD ของคุณและเริ่มใช้งานและหากทุกอย่างเรียบร้อยดีกับการตั้งค่าและแอปพลิเคชันของคุณแอปจะแสดงตามหน้าต่าง Emulator -

ตอนนี้ให้คลิกยาวที่โลโก้ TutorialsPoint ที่แสดงและคุณจะเห็นว่าภาพโลโก้นั้นเคลื่อนไหวเล็กน้อยหลังจากคลิกจากตำแหน่งนาน 1 วินาทีซึ่งเป็นเวลาที่คุณควรเริ่มลากภาพ คุณสามารถลากไปรอบ ๆ หน้าจอและวางในตำแหน่งใหม่