📜  如何在 Android 应用中使用拖放功能?

📅  最后修改于: 2022-05-13 01:55:27.947000             🧑  作者: Mango

如何在 Android 应用中使用拖放功能?

您可以利用 Android 拖放框架使您的用户能够通过图形拖放操作移动数据。这可以从您自己程序中的一个视图到另一个视图,或者在启用多窗口模式时在您的应用程序和另一个视图之间。拖动事件类、拖动侦听器以及辅助方法和类都包含在框架中。

拖放的示例用例

  1. 帮助您在实时数据上拖动指针以获取对象或事物颜色的东西
  2. 在您的移动设备的启动器屏幕上,每个程序都显示在那里,我们可以毫不费力地将应用程序图标从一个位置拖放到另一个位置。

完整事件中使用的手势

Android 中的拖放框架允许您将一个视图拖放到另一个视图,即在一个 Activity 中,如果您有两个或多个视图,您可以使用 Android 拖放将一个视图的数据从一个视图移动到另一个视图框架。例如,如果您的 Android Activity 包含两个 TextView,一个位于屏幕的一半,另一个位于另一个屏幕,则第一个 TextView 中的内容可能会被拖放到另一个 TextView。

  1. 开始:首先生成 ClipData 和 ClipData。正在传输的数据的项目。提供作为 ClipData 对象的一部分保存在 ClipData 内的 ClipDescription 对象中的元数据。对于不反映数据传输的拖放操作,您可能希望使用 null 而不是真实对象。
  2. Continuing:如果拖拽事件监听器返回true,程序就可以发起拖拽事件。拖动事件正在进行中,这意味着它已开始但尚未完成。例如,如果你想将一个名为 tv1 的 TextView 从位置 1 拖动到位置 2,则两者之间的中间状态处于连续状态。
  3. Dropped:拖动的项目在视图的边界框内释放。系统向 View 对象的侦听器发送动作类型为 ACTION DROP 的拖动事件。
  4. Ended:当用户拖放项目并调用与该拖放状态相关的所有事件时,系统会向应用程序发送一个信号,表明该拖放操作已完成并且所有需要的功能都已执行。结果,系统显示拖放事件已结束。

涉及拖动的事件

请参阅下表以了解涉及拖动的所有不同事件:

getAction() value

What does it mean?



ACTION_DRAG_ENTEREDWhen a drag shadow enters the bounding box of a View object, the drag event listener receives this event action type. When the drag shadow enters the bounding box, the listener receives the first event action type. If the listener wants to receive drag events for this action in the future, it must return a boolean true to the system.
ACTION_DRAG_LOCATIONDRAG LOCATION This event action type is received by the drag event listener of a View object when it gets an ACTION DRAG ENTERED event while the drag shadow is still within the bounding box of the View.
ACTION_DRAG_STARTEDThe drag event listener of a View object receives this event action type immediately after the application runs startDrag() and obtains a drag shadow.
ACTION_DRAG_EXITEDThis event action type is received by the drag event listener of a View object when it receives an ACTION DRAG ENTERED and at least one ACTION DRAG LOCATION event, and after the user has dragged the drag shadow outside the bounding box of the View.
ACTION_DROP

When the user releases the drag shadow over the View object, the drag event listener on the View object receives this event action type. This action type is only delivered to the listener of a View object if the listener responded true in response to the ACTION DRAG STARTED drag event. If the user releases the drag shadow on a View whose listener is not registered, or if the user releases the drag shadow on anything that is not part of the current layout, this action type is not transmitted.

If the drop is properly processed, the listener is supposed to return boolean true. If not, it should return false.

ACTION_DRAG_ENDEDNotifies a View that the drag-and-drop action is complete.

拖拽中的效果和阴影

系统显示用户在拖放操作期间拖动的图像。此图描绘了从数据移动性方面提取的数据。该图说明了其他程序的拖动过程的某些部分。

该图片称为拖动阴影。您可以通过声明 View.DragShadowBuilder 对象的方法来构建它,然后在使用 startDrag () 开始拖动时将其传递给系统。系统使用 View.DragShadowBuilder 中描述的回调方法获取拖动阴影作为其对 startDrag() 的响应的一部分。

例子

在这个例子中,我们将一个文本视图从一个位置拖放到另一个位置。

第 1 步:首先,添加应用程序的布局文件

XML


    
        
    


Kotlin
package com.geeksforgeeks.sampleDrag
  
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.util.Log
import android.defGeeksView.DragEvent
import android.defGeeksView.MotionEvent
import android.defGeeksView.DefGeeksView
import android.defGeeksView.DefGeeksViewGroup
import android.widget.LinearLayout
import kotlinx.android.synthetic.main.activity_main.*
  
class MainActivity: AppCompatActivity(), DefGeeksView.OnTouchListener, DefGeeksView.DragHappeningListener {
    private val TAG = MainActivity::class.java.simpleName
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentDefGeeksView(R.layout.activity_main)
        theDraggers()
    }
    private fun theDraggers() {
        gfgDrop.setOnTouchListener(this)
        geeksforgeeksDefGeeksView.setDragHappeningListener(this)
    }
    override fun dragHappening(defGeeksView:DefGeeksView, dragEvent: DragEvent):Boolean {
        Log.d(TAG, "dragHappening: defGeeksView->$defGeeksView\n DragEvent$dragEvent")
        when (dragEvent.action) {
            DragEvent.ACTION_DRAG_ENDED -> {
                return true
            }
            DragEvent.ACTION_DRAG_EXITED -> {
                return true
            }
            DragEvent.ACTION_DRAG_ENTERED -> {
                return true
            }
            DragEvent.ACTION_DRAG_STARTED -> {
                return true
            }
            DragEvent.ACTION_DROP -> {
                val gfgTextDefGeeksView = dragEvent.localState as DefGeeksView
                val defaultText = gfgTextDefGeeksView.parent as DefGeeksViewGroup
                defaultText.removeDefGeeksView(gfgTextDefGeeksView)
                val container = defGeeksView as LinearLayout
                container.addDefGeeksView(gfgTextDefGeeksView)
                defaultText.removeDefGeeksView(gfgTextDefGeeksView)
                gfgTextDefGeeksView.x = dragEvent.x
                gfgTextDefGeeksView.y = dragEvent.y
                defGeeksView.addDefGeeksView(gfgTextDefGeeksView)
                defGeeksView.setVisibility(DefGeeksView.VISIBLE)
                return true
            }
            DragEvent.ACTION_DRAG_LOCATION -> {
                return true
            }
            else -> return false
        }
    }
    override fun onTouch(defGeeksView:DefGeeksView, motionEvent: MotionEvent):Boolean {
        return if (motionEvent.action === MotionEvent.ACTION_DOWN) {
            val dragShadowBuilder = DefGeeksView.DragShadowBuilder(defGeeksView)
            defGeeksView.startDrag(null, dragShadowBuilder, defGeeksView, 10)
            true
        } else {
            false
        }
    }
}


第 2 步:使用 Kotlin 文件

科特林

package com.geeksforgeeks.sampleDrag
  
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.util.Log
import android.defGeeksView.DragEvent
import android.defGeeksView.MotionEvent
import android.defGeeksView.DefGeeksView
import android.defGeeksView.DefGeeksViewGroup
import android.widget.LinearLayout
import kotlinx.android.synthetic.main.activity_main.*
  
class MainActivity: AppCompatActivity(), DefGeeksView.OnTouchListener, DefGeeksView.DragHappeningListener {
    private val TAG = MainActivity::class.java.simpleName
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentDefGeeksView(R.layout.activity_main)
        theDraggers()
    }
    private fun theDraggers() {
        gfgDrop.setOnTouchListener(this)
        geeksforgeeksDefGeeksView.setDragHappeningListener(this)
    }
    override fun dragHappening(defGeeksView:DefGeeksView, dragEvent: DragEvent):Boolean {
        Log.d(TAG, "dragHappening: defGeeksView->$defGeeksView\n DragEvent$dragEvent")
        when (dragEvent.action) {
            DragEvent.ACTION_DRAG_ENDED -> {
                return true
            }
            DragEvent.ACTION_DRAG_EXITED -> {
                return true
            }
            DragEvent.ACTION_DRAG_ENTERED -> {
                return true
            }
            DragEvent.ACTION_DRAG_STARTED -> {
                return true
            }
            DragEvent.ACTION_DROP -> {
                val gfgTextDefGeeksView = dragEvent.localState as DefGeeksView
                val defaultText = gfgTextDefGeeksView.parent as DefGeeksViewGroup
                defaultText.removeDefGeeksView(gfgTextDefGeeksView)
                val container = defGeeksView as LinearLayout
                container.addDefGeeksView(gfgTextDefGeeksView)
                defaultText.removeDefGeeksView(gfgTextDefGeeksView)
                gfgTextDefGeeksView.x = dragEvent.x
                gfgTextDefGeeksView.y = dragEvent.y
                defGeeksView.addDefGeeksView(gfgTextDefGeeksView)
                defGeeksView.setVisibility(DefGeeksView.VISIBLE)
                return true
            }
            DragEvent.ACTION_DRAG_LOCATION -> {
                return true
            }
            else -> return false
        }
    }
    override fun onTouch(defGeeksView:DefGeeksView, motionEvent: MotionEvent):Boolean {
        return if (motionEvent.action === MotionEvent.ACTION_DOWN) {
            val dragShadowBuilder = DefGeeksView.DragShadowBuilder(defGeeksView)
            defGeeksView.startDrag(null, dragShadowBuilder, defGeeksView, 10)
            true
        } else {
            false
        }
    }
}

在此处获取完整代码。

结论

运行 Android 7.0(API 级别 24)或更高版本的设备启用多窗口模式,允许用户将数据从一个程序拖放到另一个程序:

  1. 最初拥有数据的应用程序称为源应用程序。当slog开始时,它就在这里。
  2. 接收数据的应用程序称为目标应用程序。这是阻力结束的点。

我们在本文中学习了如何在我们的 Android 应用程序中使用拖放功能。我们发现了一系列与拖动事件相关的事件。最后,我们演示了拖放功能。因此,利用上述方法,您可以在 Android 中创建额外的拖放应用程序。

想要一个更快节奏和更具竞争力的环境来学习 Android 的基础知识吗?
单击此处前往由我们的专家精心策划的指南,旨在让您立即做好行业准备!