Android支持的范围内的触摸手势如自来水,双击,捏,滑动,滚动,长按,拖动和甩的。拖动和甩动看起来似乎相似,但是拖动是当用户在触摸屏上拖动手指时发生的滚动类型,而当用户拖动然后快速抬起手指时则发生甩动手势。 MotionEvent通过动作代码描述触摸事件的状态。 Android支持一长串操作代码:
- ACTION_DOWN:触摸事件已开始。
- ACTION_MOVE:在触摸事件期间发生的更改(在ACTION_DOWN和ACTION_UP之间) 。
- ACTION_UP:触摸事件已完成。这包含最终发布位置。
- ACTION_CANCEL:手势已取消。
Note: You should perform same action during ACTION_CANCEL and ACTION_UP event.
重要方法
- getAction() :从事件参数中提取用户执行的操作。
重要界面
- GestureDetector.OnGestureListener :在发生特定的触摸事件时通知用户。
- GestureDetector.OnDoubleTapListener :发生双击事件时通知用户。
例子1
让我们看看对诸如ACTION_DOWN,ACTION_UP等事件执行一些简单操作的方法。
步骤1 :建立新专案
要在Android Studio中创建新项目,请参阅如何在Android Studio中创建/启动新项目。选择Kotlin作为编程语言。
步骤2:使用activity_main.xml文件
转到activity_main.xml文件,并参考以下代码。以下是activity_main.xml文件的代码。
XML
Kotlin
import android.os.Bundle
import android.util.Log
import android.view.MotionEvent
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
// logs are added for better understanding.
private const val TAG = "Gestures"
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onTouchEvent(event: MotionEvent): Boolean {
return when (event.action) {
MotionEvent.ACTION_DOWN -> {
// when we touch or tap on the screen
Log.d(TAG, "Action was DOWN")
gesture.text = "Action was DOWN"
true
}
MotionEvent.ACTION_MOVE -> {
// while pressing on the screen,
// we move our finger
Log.d(TAG, "Action was MOVE")
gesture.text = "Action was MOVE"
true
}
MotionEvent.ACTION_UP -> {
// Lifting up the finger after
// pressing on the screen
Log.d(TAG, "Action was UP")
gesture.text = "Action was UP"
true
}
MotionEvent.ACTION_CANCEL -> {
Log.d(TAG, "Action was CANCEL")
gesture.text = "Action was CANCEL"
true
}
MotionEvent.ACTION_OUTSIDE -> {
Log.d(TAG, "Movement occurred outside of screen element")
gesture.text = "Movement occurred screen element"
true
}
else -> super.onTouchEvent(event)
}
}
}
Kotlin
import android.os.Bundle
import android.util.Log
import android.view.GestureDetector
import android.view.MotionEvent
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.GestureDetectorCompat
import kotlinx.android.synthetic.main.activity_main.*
// logs are added for better understanding.
private const val TAG = "Gestures"
// We have to implement the members as well
// because we are implementing the interfaces.
class MainActivity : AppCompatActivity(), GestureDetector.OnGestureListener,
GestureDetector.OnDoubleTapListener {
private lateinit var detectorCompat: GestureDetectorCompat
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Instantiate the gesture detector with the
// application context and an implementation of
// GestureDetector.OnGestureListener
// since we have implemented these
// interfaces we can simply us the
// this keyword to refer to the current activity
detectorCompat = GestureDetectorCompat(this, this)
}
// this function connects touch events to gestures
override fun onTouchEvent(event: MotionEvent): Boolean {
return if (detectorCompat.onTouchEvent(event)) {
true
} else {
super.onTouchEvent(event)
}
}
override fun onDown(event: MotionEvent): Boolean {
Log.d(TAG, "onDown: $event")
return true
}
override fun onFling(
event1: MotionEvent,
event2: MotionEvent,
velocityX: Float,
velocityY: Float
): Boolean {
Log.d(TAG, "onFling: $event1 $event2")
return true
}
override fun onLongPress(event: MotionEvent) {
Log.d(TAG, "onLongPress: $event")
gesture.text = "Long Press"
}
override fun onScroll(
event1: MotionEvent,
event2: MotionEvent,
distanceX: Float,
distanceY: Float
): Boolean {
Log.d(TAG, "onScroll: $event1 $event2")
return true
}
override fun onShowPress(event: MotionEvent) {
Log.d(TAG, "onShowPress: $event")
gesture.text = "Press"
}
override fun onSingleTapUp(event: MotionEvent): Boolean {
Log.d(TAG, "onSingleTapUp: $event")
gesture.text = "Single Tap"
return true
}
override fun onDoubleTap(event: MotionEvent): Boolean {
Log.d(TAG, "onDoubleTap: $event")
gesture.text = "DoubleTap"
return true
}
override fun onDoubleTapEvent(event: MotionEvent): Boolean {
Log.d(TAG, "onDoubleTapEvent: $event")
// simple toast
Toast.makeText(this, "Double Tap", Toast.LENGTH_SHORT).show()
return true
}
override fun onSingleTapConfirmed(event: MotionEvent): Boolean {
Log.d(TAG, "onSingleTapConfirmed: $event")
gesture.text = "Single Tap Confirmed"
return true
}
}
步骤3:使用MainActivity.kt文件
转到MainActivity.kt文件,并参考以下代码。下面是MainActivity.kt文件的代码。在代码内部添加了注释,以更详细地了解代码。
科特林
import android.os.Bundle
import android.util.Log
import android.view.MotionEvent
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
// logs are added for better understanding.
private const val TAG = "Gestures"
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onTouchEvent(event: MotionEvent): Boolean {
return when (event.action) {
MotionEvent.ACTION_DOWN -> {
// when we touch or tap on the screen
Log.d(TAG, "Action was DOWN")
gesture.text = "Action was DOWN"
true
}
MotionEvent.ACTION_MOVE -> {
// while pressing on the screen,
// we move our finger
Log.d(TAG, "Action was MOVE")
gesture.text = "Action was MOVE"
true
}
MotionEvent.ACTION_UP -> {
// Lifting up the finger after
// pressing on the screen
Log.d(TAG, "Action was UP")
gesture.text = "Action was UP"
true
}
MotionEvent.ACTION_CANCEL -> {
Log.d(TAG, "Action was CANCEL")
gesture.text = "Action was CANCEL"
true
}
MotionEvent.ACTION_OUTSIDE -> {
Log.d(TAG, "Movement occurred outside of screen element")
gesture.text = "Movement occurred screen element"
true
}
else -> super.onTouchEvent(event)
}
}
}
Note: You may get an error on the following line:
import kotlinx.android.synthetic.main.activity_main.*
Please refer to this to fix this error.
输出:
输出说明:
- 当我们单击屏幕或按屏幕时,您可以在视频中看到“操作已停止”
- 当我们在按下鼠标或手指的同时移动它时,TextView会说Action是Move 。
- 当我松开鼠标或松开手指时,它说“操作已启动”
例子2
现在,让我们看看对事件进行一些操作的方法,例如单击,双击,长按等。 代码使用与上面相同的activity_main.xml。
使用MainActivity.kt文件:
科特林
import android.os.Bundle
import android.util.Log
import android.view.GestureDetector
import android.view.MotionEvent
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.GestureDetectorCompat
import kotlinx.android.synthetic.main.activity_main.*
// logs are added for better understanding.
private const val TAG = "Gestures"
// We have to implement the members as well
// because we are implementing the interfaces.
class MainActivity : AppCompatActivity(), GestureDetector.OnGestureListener,
GestureDetector.OnDoubleTapListener {
private lateinit var detectorCompat: GestureDetectorCompat
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Instantiate the gesture detector with the
// application context and an implementation of
// GestureDetector.OnGestureListener
// since we have implemented these
// interfaces we can simply us the
// this keyword to refer to the current activity
detectorCompat = GestureDetectorCompat(this, this)
}
// this function connects touch events to gestures
override fun onTouchEvent(event: MotionEvent): Boolean {
return if (detectorCompat.onTouchEvent(event)) {
true
} else {
super.onTouchEvent(event)
}
}
override fun onDown(event: MotionEvent): Boolean {
Log.d(TAG, "onDown: $event")
return true
}
override fun onFling(
event1: MotionEvent,
event2: MotionEvent,
velocityX: Float,
velocityY: Float
): Boolean {
Log.d(TAG, "onFling: $event1 $event2")
return true
}
override fun onLongPress(event: MotionEvent) {
Log.d(TAG, "onLongPress: $event")
gesture.text = "Long Press"
}
override fun onScroll(
event1: MotionEvent,
event2: MotionEvent,
distanceX: Float,
distanceY: Float
): Boolean {
Log.d(TAG, "onScroll: $event1 $event2")
return true
}
override fun onShowPress(event: MotionEvent) {
Log.d(TAG, "onShowPress: $event")
gesture.text = "Press"
}
override fun onSingleTapUp(event: MotionEvent): Boolean {
Log.d(TAG, "onSingleTapUp: $event")
gesture.text = "Single Tap"
return true
}
override fun onDoubleTap(event: MotionEvent): Boolean {
Log.d(TAG, "onDoubleTap: $event")
gesture.text = "DoubleTap"
return true
}
override fun onDoubleTapEvent(event: MotionEvent): Boolean {
Log.d(TAG, "onDoubleTapEvent: $event")
// simple toast
Toast.makeText(this, "Double Tap", Toast.LENGTH_SHORT).show()
return true
}
override fun onSingleTapConfirmed(event: MotionEvent): Boolean {
Log.d(TAG, "onSingleTapConfirmed: $event")
gesture.text = "Single Tap Confirmed"
return true
}
}
输出:
输出说明:
- 当我们在屏幕上单击时,它会显示“单击” ,然后确认单击,因为该事件未取消
- 当我们在屏幕上按时,它表示要按,如果我再按一次则表示长按。
- 双击时,在“文本视图”和“ Toast”中都会显示两次。
Note: onTouchEvent() is for the activity but you can attach a View.OnTouchListener object to any View object using the setOnTouchListener() method.
通过此方法,您可以在视图内触发事件时执行操作,因为OnTouchListener附加到该特定视图。例如,对于ID为“ imp”的ImageView。
img.setOnTouchListener { view, motionEvent ->
// … Respond to touch events
true
}
// for general view
findViewById
// … Respond to touch events
true
}