Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 【優才原創】Android的拖放機制

【優才原創】Android的拖放機制

編輯:關於Android編程

一、拖放機制概述

拖放操作是手指觸摸屏幕上的某一對象,然後拖動該對象,最後在屏幕的某個位置釋放該對象並執行某種操作,如刪除、卸載、啟動、復制數據等。

允許以圖形化的手勢操作完成某項任務。

拖放操作的優勢:直觀、易用、簡化操作步驟。

SDK3.0提供了支持拖放操作的編程機制,簡稱拖放機制,拖放機制是為數據移動設計的,但能夠用於其它的UI操作。如Android系統自帶的將托盤內圖標代表的應用程序以拖放的方式卸載。

拖放機制比自編程實現拖放操作更方便,優點包括:

1、提供了對所有View支持拖放操作的API,無需自定義View。

2、系統自動判斷手指的位置。

3、由系統自動繪制影子圖形。

4、系統提供了拖放對象與目標對象之間傳遞數據的機制,簡化了數據傳遞的編程。

5、提供了更多的拖放事件,如按下、抬起、釋放、進入目標區域、仍在目標區域、離開目標區域、結束拖放等六個事件。並且這些事件由系統捕捉、發送,開發者只需編寫處理這些事件的代碼。

拖放機制包括:

1、響應拖放操作事件的接口;

2、存放拖放操作相關信息的類;

3、啟動拖放操作的方法;

4、繪制拖放過程中影子圖形的類;

5、傳遞數據的類。

(二)拖放編程步驟

步驟1、設置被拖放對象的點擊或長按或觸摸的事件響應代碼,在該響應代碼中完成以下操作:

1)設置傳送給目標對象的數據;

2)設置拖放過程中繪制影子圖形的對象;

3)啟動拖放操作。

步驟2、編寫被拖放對象和拖放目標對象的響應拖放事件的代碼。

(三)相關類-ClipData

1、概述

ClipData類用於操作剪貼板中的數據,該類支持進程之間傳遞數據。在拖放編程中,該類負責被拖動對象與拖動對象之間的數據傳遞,該類支持傳遞Uri、Html文本、純文本等多種類型的數據。

2、常用方法

public static ClipDatanewPlainText(CharSequencelabel, CharSequencetext)

作用

創建一個新的ClipData對象,該對象包含MIMETYPE_TEXT_PLAIN類型的數據。

參數

label:代表剪貼板中text數據的鍵。

text:剪貼板中的數據。

public ClipData.Item getItemAt (int index)

作用

返回剪貼板中的數據。

參數

index:數據的索引值。index的值范圍[0,getItemIndex-1]

說明

若剪貼板中存放的是字符串數據,則由以下代碼取出該字符串數據:

new ClipData().getItemAt(0).getText().toString();

其中索引值0表示取出的是剪貼板中第一個

public ClipData.Item getItemAt (int index)

作用

返回剪貼板中的數據。

(四)相關類-DragShadowBuilder

1、概述

在拖拽和放下操作期間,系統會顯示一張用戶拖動的圖片。對於要移動的數據,這張圖片就代表了被拖動的數據。對於操作,這張圖片就代表了拖動操作的某些外觀。

這張圖片被叫做影子圖形,由DragShadowBuilder對象來創建。

DragShadowBuilder類是View類的內部類。

2、構造方法

public View.DragShadowBuilder (Viewview)

作用

封裝了拖拽中各種事件和控件的位置等信息。

參數

創建用於繪制影子圖形的對象,該對象的基類是View,默認情況下,該影子圖形與被拖動圖形尺寸相同,影子圖形的中心點是View對象的中心點坐標。

參數

view:被拖拽的View對象。

3、與拖拽相關的方法

public final boolean startDrag (ClipDatadata,

View.DragShadowBuildershadowBuilder, ObjectmyLocalState, int flags)

作用

開始拖拽指定的View,並把該對象傳遞給系統。

參數

創建用於繪制影子圖形的對象,該對象的基類是View,默認情況下,該影子圖形與被拖動圖形尺寸相同,影子圖形的中心點是View對象的中心點坐標。

參數

參數-data:存放數據的剪貼板對象。

shadowBuilder:操作影子圖片的對象。

myLocalState:被拖動對象與目標對象之間傳遞數據的輕量級結構的對象。

參數

flags:用於控制拖拽操作的類型,當前未定該標志值尚未定義,設置0即可。

 

(五)相關接口-OnDragListener

1、概述

OnDragListener接口用於響應拖拽的相關事件。

2、接口中聲明的方法

publicbooleanonDrag(View view, DragEvent event)

作用

封裝了拖拽中各種事件和控件的位置等信息。

參數

view:當前操作的對象,包括被拖拽對象和拖放的目標對象。

返回值

false將不會接收後續的拖動事件

true將接收後續的拖動事件。

 

(六)相關類-DragEvent

1、概述

系統用DragEvent對象存儲拖放事件的相關信息。DragEvent對象包含了一個操作類型,用於告訴監聽器在拖放過程中發生的事件。該對象還根據操作類型,包含了其它的數據。

2、拖放事件常量

 

常量

作用

ACTION_DRAG_STARTED

調用startDrag()方法,並且獲得了拖拽影子後,View對象的拖拽事件監聽器才接收這種事件操作

ACTION_DRAG_ENTERED

進入目標View區域

ACTION_DRAG_LOCATION

停留在目標View區域

ACTION_DRAG_EXITED

離開目標View區域

ACTION_DROP

釋放拖拽操作

ACTION_DRAG_ENDED

結束拖拽操作

 

有六種與拖放相關的事件,這些事件在DragEvent類中用六個常量表示,如下表所示:

常量

含義

ACTION_DRAG_ENTERED

當拖拽影子剛進入目標View對象的邊框時,View對象的拖拽事件監聽器會接收這種事件操作類型。

ACTION_DRAG_LOCATION

在View對象收到一個

ACTION_DRAG_ENTERED事件之後,並且拖拽影子依然還在這個對象的邊框之內時,這個View對象的拖拽事件監聽器會接收這種事件操作類型。

ACTION_DRAG_EXITED

View對象收到一個ACTION_DRAG_ENTERED和至少一個ACTION_DRAG_LOCATION事件之後,這個對象的事件監聽器會接受這種操作類型。

ACTION_DROP

當用戶在一個View對象之上釋放了拖拽影子,這個對象的拖拽事件監聽器就會收到這種操作類型。如果這個監聽器在響應ACTION_DRAG_STARTED拖拽事件中返回了true,那麼這種操作類型只會發送給一個View對象。如果用戶在沒有被注冊監聽器的View對象上釋放了拖拽影子,或者用戶沒有在當前布局的任何部分釋放操作影子,這個操作類型就不會被發送。如果View對象成功的處理放下事件,監聽器要返回true,否則應該返回false。

ACTION_DRAG_ENDED

當系統結束拖拽操作時,View對象拖拽監聽器會接收這種事件操作類型。這種操作類型之前不一定是ACTION_DROP事件。如果系統發送了一個ACTION_DROP事件,那麼接收ACTION_DRAG_ENDED操作類型不意味著放下操作成功了。監聽器必須調用getResult()方法來獲得響應ACTION_DROP事件中的返回值。如果ACTION_DROP事件沒有被發送,那麼getResult()會返回false。

3、常用方法

public int getAction ()

作用

返回拖拽的類型,該類型的可能值是以上的六個常量。

public ClipDatagetClipData()

作用

返回ClipData類型的對象,該對象中封裝了被拖拽對象的數據。

提示

ClipData對象在拖拽開始時創建;只有DragEvent.ACTION_DROP事件發生時,getClipData()才能返回startDrag()中第一個參數代表的ClipData對象。

public float getX()

作用

返回拖拽對象的橫坐標。

public float getY()

作用

返回拖拽對象的縱坐標。

public Object getLocateState()

作用

獲取startDrag()中的第三個參數。

二、【案例】

?目標

在屏幕左上有一個時鐘圖片,屏幕下邊有三個標簽,分別代表卸載、啟動和分享,如圖4所示:

\

 

長按時鐘,在日志窗口顯示“開始拖拽clock,拖動時鐘時,如圖-5所示:

\

 

 

當拖動時鐘進入到“啟動”標簽區域,在日志窗口顯示:clock進入啟動區,clock仍在啟動區,入圖-6所示

\

 

\

當拖動時鐘離開“啟動”區域,在日志窗口顯示:clock離開啟動區。松開時鐘將顯示拖放結束。


\

提示:

當進入目標區域時,即使沒有松手,仍會發生ACTION_DROP事件,因此在圖-7中顯示“啟動clock”。

當進入“卸載”、“分享”區域時,在日志窗口中也將顯示類似圖-6、圖-7的信息。

?思路

步驟1、MainActivity實現拖放的相關接口

publicclassMainActivity extendsActivity implementsOnDragListener,OnLongClickListener{

步驟2、定義MainActivity的成員

ImageView mivClock;

TextView mtvUninstall,mtvStart,mtvShare;

步驟3、初始化控件

privatevoidinitView() {

//創建顯示時鐘的控件

mivClock=(ImageView) findViewById(R.id.ivClock);

//設置時鐘拖拽事件的響應

mivClock.setOnDragListener(this);

//設置長按時間的響應

mivClock.setOnLongClickListener(this);

//創建代表分享、啟動和卸載的三個控件

mtvShare=(TextView) findViewById(R.id.tvShare);

mtvStart=(TextView) findViewById(R.id.tvStart);

mtvUninstall=(TextView) findViewById(R.id.tvUninstall);

//設置三個TextView響應拖拽事件的代碼

mtvShare.setOnDragListener(this);

mtvStart.setOnDragListener(this);

mtvUninstall.setOnDragListener(this);

}

步驟4、編寫響應拖放事件的代碼

//響應拖拽事件

@Override

publicbooleanonDrag(View view, DragEvent event) {

booleanresult=true;

//獲取拖拽的動作類型值

intaction=event.getAction();

switch(action) {

caseDragEvent.ACTION_DRAG_STARTED:

if(view.getId()==R.id.ivClock){

Log.i("main","開始拖拽clock");

}

break;

caseDragEvent.ACTION_DRAG_ENTERED:

if(view.getId()==R.id.tvStart){

Log.i("main","clock進入啟動區");

}

break;

caseDragEvent.ACTION_DRAG_EXITED:

if(view.getId()==R.id.tvStart){

Log.i("main","clock離開啟動區");

}

caseDragEvent.ACTION_DRAG_LOCATION:

if(view.getId()==R.id.tvStart){

Log.i("main","clock仍在啟動區");

}

caseDragEvent.ACTION_DROP:

if(view.getId()==R.id.tvShare){

Log.i("main","分享clock");

}elseif(view.getId()==R.id.tvStart){

Log.i("main","啟動clock");

}elseif(view.getId()==R.id.tvUninstall){

Log.i("main","卸載clock");

}

break;

caseDragEvent.ACTION_DRAG_ENDED:

Log.i("main","拖拽結束,在drop事件之後發生");

break;

default:

result=false;

break;

}

returnresult;

}

步驟5、編寫響應長按事件的代碼

//長按事件響應程序

@Override

publicbooleanonLongClick(View view) {

//創建實現陰影的對象

DragShadowBuilder builder=newDragShadowBuilder(view);

/*開始拖拽並把view對象傳遞給系統。作為響應startDrag()方法的一部分,

* 系統調用在View.DragShadowBuilder對象中定義的回調方法

* 來獲取拖拽影子。

*/

view.startDrag(null, builder, null, 0);

returntrue;

}

}

  1. 上一頁:
  2. 下一頁:
Copyright © Android教程網 All Rights Reserved