Skip to content

Commit

Permalink
Merge pull request #1 from Pleasurecruise/Pleasurecruise-patch-1
Browse files Browse the repository at this point in the history
[完成翻译] src/content/cookbook/effects/drag-a-widget.md cfug#1180
  • Loading branch information
Pleasurecruise authored Sep 12, 2024
2 parents e812ccb + dfa041b commit 3fa936e
Showing 1 changed file with 115 additions and 0 deletions.
115 changes: 115 additions & 0 deletions src/content/cookbook/effects/drag-a-widget.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# title: Drag a UI element
title: 创建一个可拖放的 UI 组件
description: How to implement a draggable UI element.
description: 如何实现一个可拖放的 UI 组件
js:
- defer: true
url: /assets/js/inject_dartpad.js
Expand All @@ -19,17 +20,32 @@ where the user long presses on a choice of food,
and then drags that food to the picture of the customer who
is paying for it.

拖放是移动应用程序中的一种常见交互。
当用户长按(有时称为“触摸并按住”)某个 widget 时,
另一个 widget 会出现在用户的手指下方,
用户可以将该 widget 拖动到最终位置并释放。
在这个示例中,你将构建一个拖放交互,
用户可以长按一个食物选项,
然后将该食物拖动到正在为其付款的顾客图片上。

The following animation shows the app's behavior:

下面的动画展示了应用程序的行为:

![Ordering the food by dragging it to the person](/assets/images/docs/cookbook/effects/DragAUIElement.gif){:.site-mobile-screenshot}

This recipe begins with a prebuilt list of menu items and
a row of customers.
The first step is to recognize a long press
and display a draggable photo of a menu item.

本示例从一个预先构建的菜单项列表和一排顾客开始。
第一步是识别长按操作并显示一个可拖动的菜单项图片。

## Press and drag

## 按压和拖动

Flutter provides a widget called [`LongPressDraggable`][]
that provides the exact behavior that you need to begin
a drag-and-drop interaction. A `LongPressDraggable`
Expand All @@ -39,9 +55,18 @@ As the user drags, the widget follows the user's finger.
`LongPressDraggable` gives you full control over the
widget that the user drags.

Flutter 提供了一个名为 [`LongPressDraggable`][] 的 widget,
它提供了开始拖放交互所需的确切行为。
`LongPressDraggable` widget 能够识别长按操作,
然后在用户手指附近显示一个新 widget。
当用户拖动时,该 widget 会跟随用户的手指移动。
`LongPressDraggable` 让你完全控制用户拖动的 widget。

Each menu list item is displayed with a custom
`MenuListItem` widget.

每个菜单列表项都通过一个自定义的 `MenuListItem` widget 来显示。

<?code-excerpt "lib/main.dart (MenuListItem)" replace="/^child: //g;/^\),$/)/g"?>
```dart
MenuListItem(
Expand All @@ -53,6 +78,8 @@ MenuListItem(

Wrap the `MenuListItem` widget with a `LongPressDraggable` widget.

`LongPressDraggable` widget 包裹 `MenuLIstItem` widget。

<?code-excerpt "lib/main.dart (LongPressDraggable)" replace="/^return //g;/^\),$/)/g"?>
```dart
LongPressDraggable<Item>(
Expand All @@ -77,36 +104,65 @@ This `DraggingListItem` displays a photo of the
selected food item, centered beneath
the user's finger.

在这种情况下,当用户长按 `MenuListItem` widget 时,
`LongPressDraggable` widget 会显示一个 `DraggingListItem`
这个 `DraggingListItem` 会在用户手指下方居中显示所选的食物图片。

The `dragAnchorStrategy` property is set to
[`pointerDragAnchorStrategy`][].
This property value instructs `LongPressDraggable`
to base the `DraggableListItem`'s position on the
user's finger. As the user moves a finger,
the `DraggableListItem` moves with it.

`dragAnchorStrategy` 属性设置为 [`pointerDragAnchorStrategy`][]
这个属性的值指示 `LongPressDraggable`
`DraggableListItem` 的位置基于用户的手指来定位。
当用户移动手指时,`DraggableListItem` 也会跟随移动。

Dragging and dropping is of little use if no information
is transmitted when the item is dropped.
For this reason, `LongPressDraggable` takes a `data` parameter.
In this case, the type of `data` is `Item`,
which holds information about the
food menu item that the user pressed on.

如果拖放操作在释放时没有传递任何信息,那么它几乎没有什么用处。
为此,`LongPressDraggable` 提供了一个 `data` 参数。
在这种情况下,`data` 的类型是 `Item`
它包含了用户按下的菜单项的食物信息。

The `data` associated with a `LongPressDraggable`
is sent to a special widget called `DragTarget`,
where the user releases the drag gesture.
You'll implement the drop behavior next.

`LongPressDraggable` 相关联的 `data`
会被传递到一个名为 `DragTarget` 的特殊 widget 上,
用户在此释放拖动手势。接下来你将实现拖放行为。

## Drop the draggable

## 放下可拖动组件

The user can drop a `LongPressDraggable` wherever they choose,
but dropping the draggable has no effect unless it's dropped
on top of a `DragTarget`. When the user drops a draggable on
top of a `DragTarget` widget, the `DragTarget` widget
can either accept or reject the data from the draggable.

用户可以将 `LongPressDraggable` 放在任意位置,
但除非将其放在 `DragTarget` 之上,
否则拖放操作不会有任何效果。
当用户将可拖动 widget 放在 `DragTarget` widget 上时,
`DragTarget` 可以选择接受或拒绝来自可拖动 widget 的数据。

In this recipe, the user should drop a menu item on a
`CustomerCart` widget to add the menu item to the user's cart.

在本示例中,用户应将菜单项拖放到 `CustomerCart` widget 上,
以将菜单项添加到用户的购物车中。

<?code-excerpt "lib/main.dart (CustomerCart)" replace="/^return //g;/^\),$/)/g"?>
```dart
CustomerCart(
Expand All @@ -118,6 +174,8 @@ CustomerCart(

Wrap the `CustomerCart` widget with a `DragTarget` widget.

`DragTarget` widget 包裹 `CustomCart` widget。

<?code-excerpt "lib/main.dart (DragTarget)" replace="/^child: //g;/^\),$/)/g"?>
```dart
DragTarget<Item>(
Expand All @@ -143,6 +201,11 @@ when the user drags a draggable on top of the `DragTarget`.
The `DragTarget` also recognizes when the user drops
a draggable on top of the `DragTarget` widget.

`DragTarget` 显示你现有的 widget,
并与 `LongPressDraggable` 协调,
识别用户何时将可拖动的 widget 拖动到 `DragTarget` 之上。
同时,`DragTarget` 也能识别用户何时在其上方放下一个可拖动 widget。

When the user drags a draggable on the `DragTarget` widget,
`candidateItems` contains the data items that the user is dragging.
This draggable allows you to change what your widget looks
Expand All @@ -151,30 +214,53 @@ the `Customer` widget turns red whenever any items are dragged above the
`DragTarget` widget. The red visual appearance is configured with the
`highlighted` property within the `CustomerCart` widget.

当用户将可拖动 widget 拖动到 `DragTarget` widget 上时,
`candidateItems` 包含用户正在拖动的数据项。
你可以根据用户拖动的情况更改 widget 的外观。
在本例中,`Customer` widget 在有项目拖动到 `DragTarget` widget 上方时会变成红色。
这个红色的外观是通过 `CustomerCart` widget 中的 `highlighted` 属性配置的。

When the user drops a draggable on the `DragTarget` widget,
the `onAcceptWithDetails` callback is invoked. This is when you get
to decide whether or not to accept the data that was dropped.
In this case, the item is always accepted and processed.
You might choose to inspect the incoming item to make a
different decision.

当用户将可拖动 widget 放在 `DragTarget` widget 上时,
会调用 `onAcceptWithDetails` 回调。这时你可以决定是否接受拖放的数据。
在示例中,项目总是会被接受和处理。
你也可以选择检查传入的项目以做出不同的决定。

Notice that the type of item dropped on `DragTarget`
must match the type of the item dragged from `LongPressDraggable`.
If the types are not compatible, then
the `onAcceptWithDetails` method isn't invoked.

注意,拖放到 `DragTarget` 上的项目类型必须与从 `LongPressDraggable` 拖出的项目类型匹配。
如果类型不兼容,`onAcceptWithDetails` 方法将不会被调用。

With a `DragTarget` widget configured to accept your
desired data, you can now transmit data from one part
of your UI to another by dragging and dropping.

通过配置 `DragTarget` widget 来接受你所需的数据,
现在你可以通过拖放在 UI 的不同部分之间传递数据。

In the next step,
you update the customer's cart with the dropped menu item.

在下一步中,你将更新顾客的购物车,将放下的菜单项添加进去。

## Add a menu item to a cart

## 添加一个菜单项到购物车

Each customer is represented by a `Customer` object,
which maintains a cart of items and a price total.

每位顾客由一个 `Customer` 对象表示,该对象维护一个物品购物车和总价格。

<?code-excerpt "lib/main.dart (CustomerClass)"?>
```dart
class Customer {
Expand All @@ -199,9 +285,13 @@ class Customer {
The `CustomerCart` widget displays the customer's photo,
name, total, and item count based on a `Customer` instance.

`CustomerCart` widget 根据一个 `Customer` 实例显示顾客的照片、姓名、总价和物品数量。

To update a customer's cart when a menu item is dropped,
add the dropped item to the associated `Customer` object.

要在菜单项被拖放时更新顾客的购物车,需要将放下的物品添加到关联的 `Customer` 对象中。

<?code-excerpt "lib/main.dart (AddCart)"?>
```dart
void _itemDroppedOnCustomerCart({
Expand All @@ -221,26 +311,51 @@ The `_itemDroppedOnCustomerCart` method is invoked in
layout update, the UI refreshes with the new customer's
price total and item count.

当用户将菜单项拖放到 `CustomerCart` widget 上时,
`onAcceptWithDetails()` 中会调用 `_itemDroppedOnCustomerCart` 方法。
通过将放下的物品添加到 `customer` 对象中,
并调用 `setState()` 来触发布局更新,
UI 将会刷新,显示新的顾客总价和物品数量。

Congratulations! You have a drag-and-drop interaction
that adds food items to a customer's shopping cart.

恭喜!你现在已经实现了一个将食物项添加到顾客购物车的拖放交互。

## Interactive example

## 交互示例

Run the app:

运行应用程序

* Scroll through the food items.

浏览食物项列表。

* Press and hold on one with your
finger or click and hold with the
mouse.

用手指长安其中一个食物项,或用鼠标点击并按住。

* While holding, the food item's image
will appear above the list.

按住时,食物项的图片将出现在列表上方。

* Drag the image and drop it on one of the
people at the bottom of the screen.
The text under the image updates to
reflect the charge for that person.
You can continue to add food items
and watch the charges accumulate.

将图片拖动并放到屏幕底部的某个人身上。
图片下方的文本会更新,显示该人的费用。
你可以继续添加食物项,观察费用的累积情况。

<!-- Start DartPad -->

<?code-excerpt "lib/main.dart"?>
Expand Down

0 comments on commit 3fa936e

Please sign in to comment.