如何使用 Draggable 和 DragTarget 在 Flutter 中创建拖放 UI 元素?

简介: 如何使用 Draggable 和 DragTarget 在 Flutter 中创建拖放 UI 元素?

Flutter 是一个移动应用程序 SDK,允许开发人员为 Android 和 iOS 构建和发布跨平台应用程序。Flutter 最有价值的功能之一是它能够创建可拖动的 U.I. 元素。使用此功能,您可以创建按钮,列表甚至整个屏幕,这些屏幕可以在您的应用程序中拖动。

可拖动微件允许您向任何微件添加拖放行为。DragTarget 是一个小组件,可用于指定当用户放置拖动的对象时,哪个小组件应接受放置事件。

在本文中,我们将讨论拖放、可拖动和拖动目标小部件,它们是 Flutter Toolkit 库的一部分。

关于拖放 UI 元素

拖放 UI 元素是一个新的 Flutter 小部件,允许您创建强大的自定义交互。您可以使用拖放 UI 元素来构建应用的核心交互,例如将对象从应用中的一个位置拖动到另一个位置。

Flutter 的 DragTarget 小部件允许您在允许拖动事件的页面上定义一些目标区域。例如,如果用户将图像拖到按钮上,则该按钮可能被设置为拖动事件的目标(例如,它可以接收掉落)。当拖动的物品击中目标时,它们会从目标上反弹并根据它们进入目标区域的角度在重力作用下落回原位。

可拖动的 UI 元素

可拖动微件可以在您的应用程序中创建可拖动元素。拖放功能是一项流行的功能,可让您将对象从屏幕的一部分拖放到另一部分。这对于重新排列项目、移动文件以及许多其他事情非常有用。

可拖动界面最突出的用途是在网页设计中。许多网站允许用户通过此功能重新排列其页面上的元素。除了在网站上使用外,可拖动还可用于许多其他领域,例如移动应用程序、桌面软件,甚至视频游戏!

拖动目标元素

拖动目标是一个小组件,允许您指定可以启动拖动操作的应用程序区域。DragTarget 是 GestureDetector 的一个子类,你可以使用它来检测应用中的拖动操作或手势。

DragTarget 有三种方法:

onStart – 在用户开始拖动时调用

onDrag – 当用户将手指拖过目标区域时调用

onEnd – 当用户停止拖动时调用。

使用这些小部件,您可以允许拖动整个小部件或仅拖动其中的一部分!

有两个小部件可以在 Flutter 中拖放 U.I. 元素:Draggable 和 DragTarget。可拖动允许您拖动整个小部件或其中的一部分(例如,其背景)。当多个元素响应同一事件(例如,使用不同的动画响应)时使用 DragTarget。

“可拖动”和“拖动目标”微件是允许用户与您的应用程序交互的第一步。这些小部件使您能够创建拖放体验,以便在屏幕上移动项目,包括移动 U.I. 元素或整个页面并调整其大小。

在 Flutter 应用程序开发中创建拖放体验时,可以使用可拖动小部件。可拖动小部件允许您在屏幕上拖动对象。

若要实现拖放体验,需要使用一个或多个可拖动小组件和至少一个 DragTarget 小组件。“拖动目标”构件可以是任何形状或大小,只要它具有“可拖动”构件的有效放置目标即可。

这些小部件可以处理本机元素拖动,并使用自定义图像而不是默认背景颜色自定义可拖动微件。

您可以将这些组合在一起以实现强大的自定义交互。例如,如果您希望用户能够在按钮上拖动图像,或将整个小组件从应用程序中的一个位置拖动到另一个位置,则 Draggable 和 DragTarget 是允许他们这样做的第一步。

拖放是许多应用中使用的常见交互。这是执行不同任务的简单方法,可用于各种目的。例如,您可以将文件拖到电子邮件中或在手机上移动它们。

在此示例中,我们将讨论创建简单的拖放式 UI 元素所需的初始步骤。可以将元素拖动到所需位置,也可以将它们拖放到其他元素上。

第一步是创建一个可拖动的小部件。这个小部件将定义我们元素的位置及其边界。要使您的小部件可拖动,您需要为其提供两个子项:文本小部件和带框文本的小部件。拖动文本时将显示在框中。该框将包含有关将元素放在哪里的所有必要信息。

第二步是创建一个 DragTarget 小部件,允许您指定哪些其他小部件有资格将元素拖放到它们上。如果您希望在将元素拖放到另一个元素上时具有任何特殊功能(例如更改颜色或隐藏/显示某些内容),则可以在 DragTarget 实例上设置自定义属性。

main.dart
import 'package:flutter/material.dart';
import 'package:dotted_border/dotted_border.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
  runApp(const MyApp());
}
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
        debugShowCheckedModeBanner: false, home: DemoExample());
  }
}
class DemoExample extends StatefulWidget {
  const DemoExample({Key? key}) : super(key: key);
  @override
  State<demoexample> createState() => _DemoExampleState();
}
class _DemoExampleState extends State<demoexample> {
  @override
  Widget build(BuildContext context) {
    bool isDropped = false;
    String _color = "red";
    return Scaffold(
        body: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          LongPressDraggable<string>(
            // Data is the value this Draggable stores.
            data: _color,
            feedback: Material(
              child: Container(
                height: 170.0,
                width: 170.0,
                decoration: const BoxDecoration(
                  color: Colors.redAccent,
                ),
                child: const Center(
                  child: Text(
                    'Dragging',
                    textScaleFactor: 2,
                  ),
                ),
              ),
            ),
            childWhenDragging: Container(
              height: 150.0,
              width: 150.0,
              color: Colors.grey,
              child: const Center(
                child: Text(
                  'I was here',
                  textScaleFactor: 2,
                ),
              ),
            ),
            child: Container(
              height: 150.0,
              width: 150.0,
              color: Colors.redAccent,
              child: const Center(
                child: Text(
                  'Drag me',
                  textScaleFactor: 2,
                ),
              ),
            ),
          ),
          SizedBox(
            height: MediaQuery.of(context).size.height * 0.15,
          ),
          DragTarget<string>(
            builder: (
              BuildContext context,
              List<dynamic> accepted,
              List<dynamic> rejected,
            ) {
              return DottedBorder(
                borderType: BorderType.RRect,
                radius: const Radius.circular(12),
                padding: const EdgeInsets.all(6),
                color: Colors.black,
                strokeWidth: 2,
                dashPattern: const [8],
                child: ClipRRect(
                  borderRadius: const BorderRadius.all(Radius.circular(12)),
                  child: Container(
                    height: 200,
                    width: 200,
                    color: isDropped ? Colors.redAccent : null,
                    child: Center(
                        child: Text(
                      !isDropped ? 'Drop here' : 'Dropped',
                      textScaleFactor: 2,
                    )),
                  ),
                ),
              );
            },
            onAccept: (data) {
              debugPrint('hi $data');
              setState(() {
                isDropped = true;
              });
              debugPrint('hi $isDropped');
            },
            onWillAccept: (data) {
              return data == _color;
            },
          ),
        ],
      ),
    ));
  }
}
</dynamic></dynamic></string></string></demoexample></demoexample>
复制代码

输出

网络异常,图片无法展示
|

网络异常,图片无法展示
|

结论

本文着眼于两个新的小部件,用于在 Flutter 应用程序开发中构建拖放交互。这些小部件使只需几行代码即可在 Flutter 中轻松构建成熟的拖放界面!我希望你们喜欢阅读这篇文章。

常见问题 (FAQ)

1. 颤振有拖放式用户界面吗?

Flutter 为您提供了一个小部件 LongPressDraggable,它提供了从拖放交互开始所需的确切行为。长按可拖动小部件将识别长按何时触发,并将查看用户手指附近的新小部件。当用户拖动时,小部件将跟随用户的手指。

2. 如何在 Flutter 应用程序中构建自定义下拉列表?

下拉按钮将使用叠加层进行全屏堆栈。在下拉列表后面添加全屏手势检测器,以便在用户点击屏幕上的任意位置时将其关闭。因此,叠加层使用LayerLink和CompositedTransformerFollower小部件链接到按钮。

3. 如何在 Flutter 中使用 DragTarget?

DragText < T 扩展了对象>类 Null 安全性。删除可拖动小部件时,小部件将获取数据。将可拖动对象拖动到拖动目标的顶部时,系统会询问拖动目标是否接受可拖动对象携带的任何数据。

4. 什么是可拖动小部件和拖动目标小部件?

可拖动小组件识别拖动手势的开头,并显示跟踪用户手指在屏幕上的反馈小组件。但是,如果用户将手指移动到 DragTraget 的顶部,则该目标可以接受可拖动对象携带的数据。

Flutter 中的 DragTarget 小部件将接收用户拖放的数据。它允许您将项目从一个小部件拖动到另一个小部件。因此,它是一个用于创建游戏和其他交互式用户界面的小部件。


相关文章
|
12天前
|
存储 开发框架 JavaScript
深入探讨Flutter中动态UI构建的原理、方法以及数据驱动视图的实现技巧
【6月更文挑战第11天】Flutter是高效的跨平台移动开发框架,以其热重载、高性能渲染和丰富组件库著称。本文探讨了Flutter中动态UI构建原理与数据驱动视图的实现。动态UI基于Widget树模型,状态变化触发UI更新。状态管理是关键,Flutter提供StatefulWidget、Provider、Redux等方式。使用ListView等可滚动组件和StreamBuilder等流式组件实现数据驱动视图的自动更新。响应式布局确保UI在不同设备上的适应性。Flutter为开发者构建动态、用户友好的界面提供了强大支持。
27 2
|
2天前
|
Dart Serverless Android开发
Flutter 单线程模型保证UI运行流畅
Flutter 单线程模型保证UI运行流畅
7 0
|
1月前
|
开发框架 前端开发 JavaScript
【Flutter前端技术开发专栏】Flutter中的动态UI构建与数据驱动视图
【4月更文挑战第30天】Flutter是一款高效跨平台移动开发框架,以其热重载、高性能渲染和丰富组件库著称,简化了动态UI和数据驱动视图的实现。本文深入讨论了动态UI构建原理,包括基于Widget树模型的UI更新和状态管理,如使用StatefulWidget和数据流库(如Provider、Redux)。此外,文中还介绍了实现技巧,如使用ListView等可滚动组件、StreamBuilder进行数据流驱动的UI更新,以及应用响应式布局以适应不同设备。Flutter为开发者提供了构建高效动态界面的强大工具。
【Flutter前端技术开发专栏】Flutter中的动态UI构建与数据驱动视图
|
1月前
|
前端开发 测试技术 持续交付
【Flutter 前端技术开发专栏】Flutter 中的 UI 测试与自动化测试
【4月更文挑战第30天】本文探讨了 Flutter 应用中UI测试和自动化测试的重要性,包括保障质量、提高效率和增强开发信心。Flutter提供`flutter_test`库进行Widget测试,以及`flutter_driver`进行集成测试。UI测试涵盖界面布局、交互和状态变化的验证,最佳实践建议尽早引入测试、保持用例简洁,并结合手动测试。未来,随着Flutter技术发展,UI测试和自动化测试将更加完善,助力开发高质量应用。
【Flutter 前端技术开发专栏】Flutter 中的 UI 测试与自动化测试
|
1月前
|
前端开发 搜索推荐 UED
【Flutter前端技术开发专栏】Flutter中的高级UI组件应用
【4月更文挑战第30天】探索Flutter的高级UI组件,如`TabBar`、`Drawer`、`BottomSheet`,提升应用体验和美观度。使用高级组件能节省开发时间,提供内置交互逻辑和优秀视觉效果。示例代码展示了如何实现底部导航栏、侧边导航和底部弹出菜单。同时,自定义组件允许个性化设计和功能扩展,但也带来性能优化和维护挑战。参考Flutter官方文档和教程,深入学习并有效利用这些组件。
【Flutter前端技术开发专栏】Flutter中的高级UI组件应用
|
10月前
|
iOS开发 容器
Flutter系列文章-Flutter UI进阶
在本篇文章中,我们将深入学习 Flutter UI 的进阶技巧,涵盖了布局原理、动画实现、自定义绘图和效果、以及 Material 和 Cupertino 组件库的使用。通过实例演示,你将更加了解如何创建复杂、令人印象深刻的用户界面。
19253 25
Flutter系列文章-Flutter UI进阶
|
9月前
element-ui框架的el-dialog弹出框被遮罩层挡住了/el-drawer....会生成v-model元素的组件被遮罩层挡住
element-ui框架的el-dialog弹出框被遮罩层挡住了/el-drawer....会生成v-model元素的组件被遮罩层挡住
143 1
|
9月前
|
Web App开发 前端开发 JavaScript
SAP UI5 SimpleForm 里在水平方向显示多组 Form 元素的实现方法试读版
SAP UI5 SimpleForm 里在水平方向显示多组 Form 元素的实现方法试读版
|
9月前
|
XML 数据格式
SAP UI5 应用 manifest.json 文件里 Routes 数组元素的相对顺序,不可忽视的试读版
SAP UI5 应用 manifest.json 文件里 Routes 数组元素的相对顺序,不可忽视的试读版
|
9月前
|
XML 前端开发 开发者
SAP UI5 FileUploader 使用的隐藏 iframe 和 form 元素的设计明细
SAP UI5 FileUploader 使用的隐藏 iframe 和 form 元素的设计明细