Android - Kéo và thả
Khung kéo / thả Android cho phép người dùng của bạn di chuyển dữ liệu từ Chế độ xem này sang Chế độ xem khác trong bố cục hiện tại bằng cách sử dụng cử chỉ kéo và thả đồ họa. Kể từAPI 11 kéo và thả chế độ xem vào các chế độ xem hoặc nhóm chế độ xem khác được hỗ trợ. Khung bao gồm ba thành phần quan trọng sau để hỗ trợ chức năng kéo và thả:
Drag event class.
Drag listeners.
Helper methods and classes.
Quá trình kéo / thả
Về cơ bản có bốn bước hoặc trạng thái trong quá trình kéo và thả -
Started - Sự kiện này xảy ra khi bạn bắt đầu kéo một mục trong một bố cục, ứng dụng của bạn gọi phương thức startDrag () để yêu cầu hệ thống bắt đầu kéo. Các đối số bên trong phương thức startDrag () cung cấp dữ liệu được kéo, siêu dữ liệu cho dữ liệu này và một lệnh gọi lại để vẽ bóng kéo.
Trước tiên, hệ thống sẽ phản hồi bằng cách gọi lại ứng dụng của bạn để lấy bóng kéo. Sau đó, nó hiển thị bóng kéo trên thiết bị.
Tiếp theo, hệ thống sẽ gửi một sự kiện kéo với loại hành động ACTION_DRAG_STARTED tới trình nghe sự kiện kéo đã đăng ký cho tất cả các đối tượng View trong bố cục hiện tại.
Để tiếp tục nhận các sự kiện kéo, bao gồm cả sự kiện thả có thể xảy ra, người nghe sự kiện kéo phải quay lại true, Nếu trình xử lý sự kiện kéo trả về false, thì nó sẽ không nhận được các sự kiện kéo cho hoạt động hiện tại cho đến khi hệ thống gửi một sự kiện kéo với loại hành động ACTION_DRAG_ENDED.
Continuing- Người dùng tiếp tục kéo. Hệ thống gửi hành động ACTION_DRAG_ENTERED theo sau hành động ACTION_DRAG_LOCATION tới trình xử lý sự kiện kéo đã đăng ký cho Chế độ xem nơi điểm kéo đi vào. Người nghe có thể chọn thay đổi diện mạo của đối tượng Chế độ xem của nó để đáp ứng với sự kiện hoặc có thể phản ứng bằng cách đánh dấu Chế độ xem của nó.
Trình xử lý sự kiện kéo nhận được hành động ACTION_DRAG_EXITED sau khi người dùng đã di chuyển bóng kéo ra bên ngoài hộp giới hạn của Chế độ xem.
Dropped- Người dùng giải phóng mục được kéo trong hộp giới hạn của Chế độ xem. Hệ thống sẽ gửi cho người nghe của đối tượng View một sự kiện kéo với kiểu hành động ACTION_DROP.
Ended - Ngay sau khi loại hành động ACTION_DROP, hệ thống sẽ gửi sự kiện kéo với loại hành động ACTION_DRAG_ENDED để cho biết rằng hoạt động kéo đã kết thúc.
Lớp DragEvent
Các DragEventđại diện cho một sự kiện được hệ thống gửi đi vào những thời điểm khác nhau trong một thao tác kéo và thả. Lớp này cung cấp một số Hằng số và các phương thức quan trọng mà chúng tôi sử dụng trong quá trình Kéo / Thả.
Hằng số
Sau đây là tất cả các hằng số nguyên có sẵn như một phần của lớp DragEvent.
Sr.No. | Hằng số & Mô tả |
---|---|
1 | ACTION_DRAG_STARTED Báo hiệu khi bắt đầu thao tác kéo và thả. |
2 | ACTION_DRAG_ENTERED Báo hiệu cho một Dạng xem rằng điểm kéo đã đi vào hộp giới hạn của Dạng xem. |
3 | ACTION_DRAG_LOCATION Được gửi tới Chế độ xem sau ACTION_DRAG_ENTERED nếu bóng kéo vẫn nằm trong hộp giới hạn của đối tượng Chế độ xem. |
4 | ACTION_DRAG_EXITED Các tín hiệu cho thấy người dùng đã di chuyển bóng kéo ra bên ngoài hộp giới hạn của Chế độ xem. |
5 | ACTION_DROP Báo hiệu cho một Dạng xem rằng người dùng đã thả bóng kéo và điểm kéo nằm trong hộp giới hạn của Dạng xem. |
6 | ACTION_DRAG_ENDED Báo hiệu cho Chế độ xem rằng thao tác kéo và thả đã kết thúc. |
Phương pháp
Sau đây là một vài phương thức quan trọng và được sử dụng thường xuyên nhất có sẵn như một phần của lớp DragEvent.
Sr.No. | Hằng số & Mô tả |
---|---|
1 | int getAction() Kiểm tra giá trị hành động của sự kiện này .. |
2 | ClipData getClipData() Trả về đối tượng ClipData được gửi đến hệ thống như một phần của lệnh gọi startDrag (). |
3 | ClipDescription getClipDescription() Trả về đối tượng ClipDescription có trong ClipData. |
4 | boolean getResult() Trả về chỉ báo kết quả của thao tác kéo và thả. |
5 | float getX() Nhận tọa độ X của điểm kéo. |
6 | float getY() Nhận tọa độ Y của điểm kéo. |
7 | String toString() Trả về biểu diễn chuỗi của đối tượng DragEvent này. |
Lắng nghe sự kiện kéo
Nếu bạn muốn bất kỳ chế độ xem nào của mình trong Bố cục sẽ phản hồi sự kiện Kéo thì chế độ xem của bạn sẽ triển khai View.OnDragListener hoặc thiết lập onDragEvent(DragEvent)phương thức gọi lại. Khi hệ thống gọi phương thức hoặc trình nghe, nó sẽ chuyển cho họ một đối tượng DragEvent đã giải thích ở trên. Bạn có thể có cả phương thức nghe và phương thức gọi lại cho đối tượng View. Nếu điều này xảy ra, trước tiên hệ thống gọi người nghe và sau đó xác định gọi lại miễn là người nghe trả về true.
Sự kết hợp của phương thức onDragEvent (DragEvent) và View.OnDragListener tương tự như sự kết hợp củaonTouchEvent() và View.OnTouchListener được sử dụng với các sự kiện cảm ứng trong các phiên bản Android cũ.
Bắt đầu sự kiện kéo
Bạn bắt đầu với việc tạo ClipData và ClipData.Itemcho dữ liệu được di chuyển. Là một phần của đối tượng ClipData , cung cấp siêu dữ liệu được lưu trữ trongClipDescriptionđối tượng trong ClipData. Đối với thao tác kéo và thả không đại diện cho chuyển động của dữ liệu, bạn có thể muốn sử dụngnull thay vì một đối tượng thực tế.
Tiếp theo bạn có thể mở rộng gia hạn View.DragShadowBuilderđể tạo bóng kéo để kéo chế độ xem hoặc đơn giản bạn có thể sử dụng View.DragShadowBuilder (Chế độ xem) để tạo bóng kéo mặc định có cùng kích thước với đối số Chế độ xem được truyền cho nó, với điểm tiếp xúc nằm ở giữa bóng kéo.
Thí dụ
Ví dụ sau cho thấy chức năng của Kéo và Thả đơn giản bằng cách sử dụng View.setOnLongClickListener(), View.setOnTouchListener()và View.OnDragEventListener().
Bươc | Sự miêu tả |
---|---|
1 | Bạn sẽ sử dụng Android studio IDE để tạo ứng dụng Android và đặt tên là Ứng dụng của tôi theo gói com.example.saira_000.myapplication . |
2 | Sửa đổi tệp src / MainActivity.java và thêm mã để xác định trình xử lý sự kiện cũng như phương thức gọi lại cho hình ảnh logo được sử dụng trong ví dụ. |
3 | Sao chép hình ảnh abc.png trong thư mục res / drawable- * . Bạn có thể sử dụng hình ảnh với độ phân giải khác nhau trong trường hợp bạn muốn cung cấp cho các thiết bị khác nhau. |
4 | Sửa đổi tệp XML bố cục res / layout / activity_main.xml để xác định chế độ xem mặc định của hình ảnh logo. |
5 | Chạy ứng dụng để khởi chạy trình giả lập Android và xác minh kết quả của các thay đổi được thực hiện trong ứng dụng. |
Sau đây là nội dung của tệp hoạt động chính được sửa đổi src/MainActivity.java. Tệp này có thể bao gồm từng phương thức vòng đời cơ bản.
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;
}
}
});
}
}
Sau đây sẽ là nội dung của res/layout/activity_main.xml tập tin -
Trong đoạn mã sau abc chỉ ra logo của 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>
Sau đây sẽ là nội dung của res/values/strings.xml để xác định hai hằng số mới -
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">My Application</string>
</resources>
Sau đây là nội dung mặc định của 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>
Hãy cố gắng chạy My Applicationứng dụng. Tôi cho rằng bạn đã tạo raAVDtrong khi thiết lập môi trường. Để chạy ứng dụng từ Android Studio, hãy mở một trong các tệp hoạt động của dự án của bạn và nhấp vào
Bây giờ, hãy nhấp lâu vào biểu trưng TutorialsPoint được hiển thị và bạn sẽ thấy hình ảnh biểu trưng đó di chuyển một chút sau khi nhấp chuột lâu từ vị trí của nó, đây là thời điểm bạn nên bắt đầu kéo hình ảnh. Bạn có thể kéo nó xung quanh màn hình và thả nó vào một vị trí mới.