Android - przeciągnij i upuść
Struktura przeciągania / upuszczania systemu Android umożliwia użytkownikom przenoszenie danych z jednego widoku do innego widoku w bieżącym układzie za pomocą graficznego gestu przeciągania i upuszczania. Stan na dzieńAPI 11 obsługiwane jest przeciąganie i upuszczanie widoku na inne widoki lub grupy widoków. Framework zawiera następujące trzy ważne komponenty obsługujące funkcję przeciągnij i upuść -
Drag event class.
Drag listeners.
Helper methods and classes.
Proces przeciągania / upuszczania
Zasadniczo istnieją cztery kroki lub stany w procesie przeciągania i upuszczania -
Started - To zdarzenie występuje, gdy zaczynasz przeciągać element w układzie, aplikacja wywołuje metodę startDrag () , aby nakazać systemowi rozpoczęcie przeciągania. Argumenty wewnątrz metody startDrag () zawierają dane do przeciągnięcia, metadane dla tych danych oraz wywołanie zwrotne do rysowania cienia przeciągania.
System najpierw odpowiada, oddzwaniając do aplikacji, aby uzyskać cień przeciągania. Następnie wyświetla cień przeciągania na urządzeniu.
Następnie system wysyła zdarzenie przeciągania z typem akcji ACTION_DRAG_STARTED do zarejestrowanych detektorów zdarzeń przeciągania dla wszystkich obiektów View w bieżącym układzie.
Aby nadal otrzymywać zdarzenia przeciągania, w tym możliwe zdarzenie upuszczania, detektor zdarzenia przeciągania musi powrócić true, Jeśli detektor zdarzeń przeciągania zwróci wartość false, nie będzie odbierał zdarzeń przeciągania dla bieżącej operacji, dopóki system nie wyśle zdarzenia przeciągania z typem akcji ACTION_DRAG_ENDED.
Continuing- Użytkownik kontynuuje przeciąganie. System wysyła akcję ACTION_DRAG_ENTERED, po której następuje akcja ACTION_DRAG_LOCATION do zarejestrowanego detektora zdarzeń przeciągania dla Widoku, do którego wchodzi punkt przeciągania. Słuchacz może zdecydować się zmienić wygląd swojego obiektu View w odpowiedzi na zdarzenie lub może zareagować, podświetlając swój View.
Odbiornik zdarzenia przeciągania otrzymuje akcję ACTION_DRAG_EXITED po tym, jak użytkownik przesunie cień przeciągania poza ramkę ograniczającą Widoku.
Dropped- Użytkownik puszcza przeciągnięty element w obwiedni Widoku. System wysyła detektorowi obiektu View zdarzenie przeciągania z typem akcji ACTION_DROP.
Ended - Zaraz po typie akcji ACTION_DROP system wysyła zdarzenie przeciągania z typem akcji ACTION_DRAG_ENDED, aby wskazać, że operacja przeciągania została zakończona.
Klasa DragEvent
Plik DragEventreprezentuje zdarzenie, które jest wysyłane przez system w różnych momentach podczas operacji przeciągania i upuszczania. Ta klasa zapewnia kilka stałych i ważnych metod, których używamy podczas procesu przeciągania / upuszczania.
Stałe
Poniżej znajdują się wszystkie stałe liczby całkowite dostępne jako część klasy DragEvent.
Sr.No. | Stałe i opis |
---|---|
1 |
ACTION_DRAG_STARTED Sygnalizuje rozpoczęcie operacji przeciągnij i upuść. |
2 |
ACTION_DRAG_ENTERED Sygnalizuje widokowi, że punkt przeciągania wszedł w obwiednię widoku. |
3 | ACTION_DRAG_LOCATION Wysyłane do widoku po ACTION_DRAG_ENTERED, jeśli cień przeciągania nadal znajduje się w obwiedni obiektu widoku. |
4 | ACTION_DRAG_EXITED Sygnalizuje, że użytkownik przesunął cień przeciągania poza obwiednię Widoku. |
5 | ACTION_DROP Sygnalizuje widokowi, że użytkownik zwolnił cień do przeciągania, a punkt przeciągania znajduje się w obwiedni widoku. |
6 |
ACTION_DRAG_ENDED Sygnalizuje widokowi, że operacja przeciągania i upuszczania została zakończona. |
Metody
Poniżej znajduje się kilka ważnych i najczęściej używanych metod dostępnych w ramach klasy DragEvent.
Sr.No. | Stałe i opis |
---|---|
1 | int getAction() Sprawdź wartość akcji tego zdarzenia. |
2 | ClipData getClipData() Zwraca obiekt ClipData wysłany do systemu jako część wywołania startDrag (). |
3 |
ClipDescription getClipDescription() Zwraca obiekt ClipDescription zawarty w ClipData. |
4 |
boolean getResult() Zwraca wskazanie wyniku operacji przeciągania i upuszczania. |
5 |
float getX() Pobiera współrzędną X punktu przeciągania. |
6 | float getY() Pobiera współrzędną Y punktu przeciągania. |
7 | String toString() Zwraca ciąg reprezentujący ten obiekt DragEvent. |
Nasłuchiwanie wydarzenia Drag
Jeśli chcesz, aby którykolwiek z twoich widoków w układzie odpowiadał zdarzeniu Przeciągnij, twój widok albo implementuje View.OnDragListener lub setup onDragEvent(DragEvent)metoda wywołania zwrotnego. Kiedy system wywołuje metodę lub detektor, przekazuje im obiekt DragEvent wyjaśniony powyżej. Możesz mieć zarówno detektor, jak i metodę wywołania zwrotnego dla obiektu View. W takim przypadku system najpierw wywołuje nasłuchiwanie, a następnie definiuje wywołanie zwrotne, o ile listener zwraca wartość true.
Kombinacja metody onDragEvent (DragEvent) i View.OnDragListener jest analogiczna do kombinacji metodyonTouchEvent() i View.OnTouchListener używane ze zdarzeniami dotykowymi w starszych wersjach Androida.
Rozpoczynanie wydarzenia Drag
Zaczynasz od stworzenia ClipData i ClipData.Itemza przenoszone dane. Jako część obiektu ClipData podaj metadane, które są przechowywane w plikuClipDescriptionobiekt w ClipData. W przypadku operacji przeciągania i upuszczania, która nie reprezentuje przenoszenia danych, warto użyćnull zamiast rzeczywistego obiektu.
Następnie możesz przedłużyć przedłużenie View.DragShadowBuilderaby utworzyć cień do przeciągania do przeciągania widoku lub po prostu możesz użyć View.DragShadowBuilder (View), aby utworzyć domyślny cień do przeciągania o takim samym rozmiarze, jak przekazany argument View, z punktem dotykowym wyśrodkowanym w cieniu przeciągania.
Przykład
Poniższy przykład przedstawia funkcjonalność prostego przeciągania i upuszczania przy użyciu View.setOnLongClickListener(), View.setOnTouchListener()i View.OnDragEventListener().
Krok | Opis |
---|---|
1 | Użyjesz Android Studio IDE do stworzenia aplikacji na Androida i nazwij ją jako Moja aplikacja w pakiecie com.example.saira_000.myapplication . |
2 | Zmodyfikuj plik src / MainActivity.java i dodaj kod, aby zdefiniować detektory zdarzeń, a także metody wywołania zwrotnego dla obrazu logo użytego w przykładzie. |
3 | Skopiuj obraz abc.png do folderów res / drawable- * . Możesz użyć obrazów o różnej rozdzielczości, jeśli chcesz je udostępnić na różne urządzenia. |
4 | Zmodyfikuj plik XML układu res / layout / activity_main.xml, aby zdefiniować domyślny widok obrazów logo. |
5 | Uruchom aplikację, aby uruchomić emulator Androida i zweryfikować wynik zmian wprowadzonych w aplikacji. |
Poniżej znajduje się zawartość zmodyfikowanego pliku głównego działania src/MainActivity.java. Ten plik może zawierać każdą z podstawowych metod cyklu życia.
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;
}
}
});
}
}
Poniżej będzie treść res/layout/activity_main.xml plik -
W poniższym kodzie abc wskazuje logo 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>
Poniżej będzie treść res/values/strings.xml zdefiniować dwie nowe stałe -
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">My Application</string>
</resources>
Poniżej znajduje się domyślna zawartość 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>
Spróbujmy uruchomić Twój My Applicationpodanie. Zakładam, że stworzyłeś swójAVDpodczas konfigurowania środowiska. Aby uruchomić aplikację z Android Studio, otwórz jeden z plików aktywności projektu i kliknij
Teraz kliknij długo na wyświetlane logo TutorialsPoint, a zobaczysz, że obraz logo przesuwa się trochę po 1 sekundowym kliknięciu z jego miejsca, to czas, w którym powinieneś zacząć przeciągać obraz. Możesz przeciągnąć go po ekranie i upuścić w nowym miejscu.