首页 > 其他分享 >flutter 上下文菜单的使用

flutter 上下文菜单的使用

时间:2023-03-05 14:11:53浏览次数:49  
标签:菜单 anchors TextSelectionToolbarTextButton context ContextMenuController 上下文 flut

1.什么是上下文菜单

上下文菜单主要是指一种通过上下文贯穿多级组件的特定的弹窗菜单,如pc端的鼠标右击菜单移动端的长按菜单或内容选择菜单
image

2.在flutter中使用上下文菜单

需要使用ContextMenuController创建上下文菜单控制器实例,并使用show方法弹出上下文菜单,首先我们来看一下ContextMenuController有那些可用的参数与方法。

ContextMenuController构造函数参数

参数名 类型 必选 描述
onRemove VoidCallback 当上下文菜单被移除时触发

ContextMenuController可使用的成员变量

变量名 类型 描述
isShown bool 当前上下文菜单是否处于展示状态

ContextMenuController可调用的方法

方法名 参数 返回值 描述
show {
  required BuildContext context,
  required WidgetBuilder contextMenuBuilder,
  Widget? debugRequiredFor
}
void 展示上下文菜单
remove - void 从视图中删除上下文菜单
markNeedsBuild - void 重建视图中的上下文菜单

从show方法的源码可以看出每次展示上下菜单时都会销毁已展示的上下文菜单,并将新创建的OverlayEntry实例存放在静态变量_menuOverlayEntry上,上下文菜单的本质是使用Overlay+OverlayEntry实现的浮层,完全可以参考ContextMenuController实现自己的上下文菜单组件。
image

2.1默认上下文菜单

展示上下使用show方法即可,官方提供了AdaptiveTextSelectionToolbar.buttonItems方法创建简单的上下文菜单,需要注意上下文菜单需要使用anchors参数指定菜单展示位置。

class NoteList extends StatefulWidget {
    const NoteList({super.key});
    @override
    State<NoteList> createState() => _NoteListState();
}

class _NoteListState extends State<NoteList> {
    /// 上下文菜单控制器
    final ContextMenuController _contextMenuController = ContextMenuController();
    Widget _buildListItem(){
        return GestureDetector(
            onSecondaryTapUp: (details) {
               _showContextMenu(details.globalPosition);
            }
        );
    }
    void _showContextMenu(Offset position){
        /// 展示上下文菜单
        _contextMenuController.show(
            context: context,
            contextMenuBuilder: (context) {
                return AdaptiveTextSelectionToolbar.buttonItems(
                    /// 指定菜单展示的位置,使用鼠标右击的全局位置信息
                    anchors: TextSelectionToolbarAnchors(primaryAnchor: position),
                    buttonItems: <ContextMenuButtonItem>[
                        ContextMenuButtonItem(
                            label: '删除',
                            onPressed: () {}
                        )
                    ]
                );
            }
        );
    }
}

在windows平台的效果
image

2.2.自定义上下文菜单

定位到AdaptiveTextSelectionToolbar的源码可以发现buttonItems的数据最终会根据所属平台不同而使用对应的模板渲染。
image
从AdaptiveTextSelectionToolbar的build代码可以看出我们只需要使用children属性就可以实现自定义上下文菜单项。
image
如下代码使用安卓的上下文明细行渲染

_contextMenuController.show(
    context: context,
    contextMenuBuilder: (context) {
        return AdaptiveTextSelectionToolbar(
          anchors: TextSelectionToolbarAnchors(primaryAnchor: position),
          children: [
            TextSelectionToolbarTextButton(
              padding: TextSelectionToolbarTextButton.getPadding(0, 1),
              onPressed: () {},
              child: const Text("删除"),
            ),
             TextSelectionToolbarTextButton(
              padding: TextSelectionToolbarTextButton.getPadding(0, 1),
              onPressed: () {},
              child: const Text("复制"),
            )
          ],
        );
    }
);

在windows平台的效果如下
image
可以看到每行的渲染已发生了变化,但是布局任然是纵向排列,而安卓平台的上下文菜单是横向排列的,那么我们可以不可以让windows平台的上下文菜单如安卓平台一样横向排列或者做出多级菜单呢?当然完全可以,我们只需要在contextMenuBuilder中返回自定义的上下文菜单渲染组件就可以了,如下在windows平台使用横向布局菜单。

_contextMenuController.show(
    context: context,
    contextMenuBuilder: (context) {
       var anchors = TextSelectionToolbarAnchors(primaryAnchor: position);
        return TextSelectionToolbar(
          anchorAbove: anchors.primaryAnchor,
          anchorBelow: anchors.secondaryAnchor == null
              ? anchors.primaryAnchor
              : anchors.secondaryAnchor!,
          children: [
            TextSelectionToolbarTextButton(
              padding: TextSelectionToolbarTextButton.getPadding(0, 1),
              onPressed: () {},
              child: const Text("删除"),
            ),
            TextSelectionToolbarTextButton(
              padding: TextSelectionToolbarTextButton.getPadding(0, 1),
              onPressed: () {},
              child: const Text("复制"),
            )
          ],
        );
    }
);

在windows平台使用安卓的横向布局后上下文菜单的效果
image

标签:菜单,anchors,TextSelectionToolbarTextButton,context,ContextMenuController,上下文,flut
From: https://www.cnblogs.com/ibxk/p/17180352.html

相关文章