flutter 弹窗之系列一

自定义不受Navigator影响的弹窗

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  void _dialogController1() {
    DialogController alert = DialogController.alert(
      title: "Title",
      subTitle: "SubTitle",
      onCancel: () {
        debugPrint("alert cancel");
      },
      run: () async {
        // 一些耗时操作
        return true;
      },
    );
    alert.show(context);
  }

  void _dialogController2(){
    DialogController loadingAlert = DialogController.loadingAlert();
    loadingAlert.showWithTimeout(context, timeout: 10);
    // await 其他耗时操作
    loadingAlert.close();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
          child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          GestureDetector(
            onTap: () {
              _dialogController1();
            },
            child: const Text(
              '\n点击显示弹窗一\n',
            ),
          ),
          GestureDetector(
            onTap: () {
              _dialogController2();
            },
            child: const Text(
              '\n点击显示弹窗二\n',
            ),
          ),
        ],
      )),
    );
  }
}

class BaseDialog {
  BaseDialog(this._barrierDismissible, this._alignment);

  /// 点击背景是否关闭弹窗
  final bool _barrierDismissible;
  final AlignmentGeometry _alignment;

  /// 页面状态,用来做动画判断
  bool _isCloseState = true;

  /// 动画时长
  final _milliseconds = 240;

  /// 初始化dialog的内容
  /// [isClose]用来标识动画的状态
  /// [milliseconds]用来标识动画时长
  initContentView(
      Widget Function(BuildContext context, bool isClose, int milliseconds)
          builder) {
    _overlayEntry = OverlayEntry(
      builder: (context) {
        return Stack(
          alignment: _alignment,
          children: <Widget>[
            // 背景
            Positioned.fill(
              child: GestureDetector(
                onTap: () {
                  // 点击背景关闭页面
                  if (_barrierDismissible) close();
                },
                child: AnimatedOpacity(
                  opacity: _isCloseState ? 0.0 : 1,
                  duration: Duration(milliseconds: _milliseconds),
                  child: Container(
                    color: Colors.black.withOpacity(0.5),
                  ),
                ),
              ),
            ),
            builder(context, _isCloseState, _milliseconds),
          ],
        );
      },
    );
  }

  late OverlayEntry _overlayEntry;
  bool _isPop = true;

  /// 显示弹窗
  /// 小等于0不设置超时
  void show(BuildContext context, int timeout) async {
    //显示弹窗
    Overlay.of(context).insert(_overlayEntry);
    // 稍微延迟一下,不然动画不动
    await Future.delayed(const Duration(milliseconds: 10));
    _isCloseState = false;
    // 重新build启动动画
    _overlayEntry.markNeedsBuild();
    _isPop = true;
    // 启动计时器,timeout秒后执行关闭操作
    if (timeout > 0) {
      Future.delayed(Duration(seconds: timeout), () => close());
    }
  }

  /// 关闭弹窗
  Future<void> close() async {
    if (_isPop) {
      _isPop = false;
      _isCloseState = true;
      // 重新build启动动画
      _overlayEntry.markNeedsBuild();
      // 等待动画结束后再移除涂层
      await Future.delayed(Duration(milliseconds: _milliseconds));
      _overlayEntry.remove();
      onClose();
    }
  }

  void Function() onClose = () {};
}

class DialogController {
  DialogController(this._baseDialog);

  final BaseDialog _baseDialog;

  /// 关闭弹窗
  close() {
    _baseDialog.close();
  }

  /// 显示弹窗
  show(BuildContext context) {
    _baseDialog.show(context, 0);
  }

  /// 显示一个默认带超时的弹窗
  /// 小等于0不设置超时
  void showWithTimeout(BuildContext context, {int timeout = 20}) {
    _baseDialog.show(context, timeout);
  }

  /// 创造一个普通样式的alert弹窗
  /// 它显示在屏幕中央,具有一个标题和内容描述文本,
  /// [onBarrierTap]当点击背景时触发
  factory DialogController.alert({
    required String title,
    required String subTitle,
    bool barrierDismissible = true,
    Future<bool> Function()? run,
    void Function()? onCancel,
  }) {
    final dialog = BaseDialog(
      barrierDismissible,
      AlignmentDirectional.center,
    );
    if (onCancel != null) {
      dialog.onClose = onCancel;
    }
    dialog.initContentView((context, isClose, int milliseconds) {
      return AnimatedOpacity(
        opacity: isClose ? 0.0 : 1,
        duration: Duration(milliseconds: milliseconds),
        child: AlertDialog(
          title: Text(title),
          content: Text(subTitle),
          actions: [
            FilledButton.tonal(
              onPressed: () {
                dialog.close();
              },
              child: const Text("取消"),
            ),
            FilledButton(
              onPressed: () async {
                if (run != null) {
                  final r = await run();
                  if (r) dialog.close();
                } else {
                  dialog.close();
                }
              },
              child: const Text("确认"),
            )
          ],
        ),
      );
    });
    return DialogController(dialog);
  }

  factory DialogController.loadingAlert({
    String? title,
    String? subTitle,
  }) {
    final dialog = BaseDialog(
      false,
      AlignmentDirectional.center,
    );
    dialog.initContentView((context, isClose, int milliseconds) {
      return AnimatedOpacity(
        opacity: isClose ? 0.0 : 1,
        duration: Duration(milliseconds: milliseconds),
        child: AlertDialog(
          title: Text(title ?? "正在加载"),
          content: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              const SizedBox(height: 16),
              const SizedBox(
                width: 24,
                height: 24,
                child: CircularProgressIndicator(
                  strokeWidth: 3,
                ),
              ), // 添加一个加载指示器
              const SizedBox(height: 16),
              Text(subTitle ?? '请等待...'), // 提示用户等待
            ],
          ),
        ),
      );
    });
    return DialogController(dialog);
  }
}

系统Dialog的使用

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  void _showDialog() {
    showDialog(
      context: context,
      barrierColor: Colors.transparent, //设置透明底色,自定义也可能会用到
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text("测试标题"),
          content: const Text("测试内容"),
          actions: [
            TextButton(
              onPressed: () {},
              child: const Text('确认'),
            ),
            TextButton(
              onPressed: () {},
              child: const Text('取消'),
            ),
          ],
          shape:
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: GestureDetector(
          onTap: () {
            _showDialog();
          },
          child: const Text(
            '\n点击显示弹窗一\n',
          ),
        ),
      ),
    );
  }
}

定制Dialog

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  void _showDialog() {
    showDialog(
      context: context,
      barrierColor: Colors.transparent, //设置透明底色
      builder: (BuildContext context) {
        return const DialogView(
          title: "测试标题",
          message: "测试内容",
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: GestureDetector(
          onTap: () {
            _showDialog();
          },
          child: const Text(
            '\n点击显示弹窗一\n',
          ),
        ),
      ),
    );
  }
}

//这个弹层一般是通过 showDialog 弹出,实际上相当于跳转了一个新界面,因此返回需通过 Navigator pop回去
class DialogView extends Dialog {
  final String title;
  final String message;

  const DialogView({Key? key, required this.title, required this.message})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.transparent,
      body: Center(
        child: Container(
          width: 100,
          height: 150,
          color: Colors.black.withOpacity(0.7),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Text(title,
                  style: const TextStyle(color: Colors.white, fontSize: 14.0)),
              Text(message,
                  style: const TextStyle(color: Colors.white, fontSize: 14.0)),
              TextButton(
                onPressed: () {
                  //showDialog相当于push,因此自己返回需要pop
                  Navigator.pop(context);
                },
                child: const Text('返回'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

获取组件偏移量

//组件渲染完成之后,可以通过组价你的context参数,间接获取组件的偏移量
    RenderBox box = context.findRenderObject() as RenderBox;
    final local = box.localToGlobal(Offset.zero);
    debugPrint("组件偏移量:$local");

DropdownButton

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  String? selectValue;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: DropdownButton(
          hint: const Text("请选择您要的号码:"),
          items: getItems(),
          value: selectValue,
          onChanged: (value) {
            debugPrint(value);
            setState(() {
              selectValue = value;
            });
          },
        )
      ),
    );
  }

  List<DropdownMenuItem<String>> getItems() {
    List<DropdownMenuItem<String>> items = [];
    items.add(const DropdownMenuItem(child: Text("AA"), value: "11"));
    items.add(const DropdownMenuItem(child: Text("BB"), value: "22",));
    items.add(const DropdownMenuItem(child: Text("CC"), value: "33",));
    items.add(const DropdownMenuItem(child: Text("DD"), value: "44",));
    items.add(const DropdownMenuItem(child: Text("EE"), value: "55",));
    return items;
  }

}

底部弹窗BottomSheet

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  void _showDialog(){
    showModalBottomSheet(
        context: context,
        builder: (BuildContext context) {
          return Column(
            mainAxisSize: MainAxisSize.min, // 设置最小的弹出
            children: <Widget>[
              ListTile(
                leading: const Icon(Icons.photo_camera),
                title: const Text("Camera"),
                onTap: () async {

                },
              ),
              ListTile(
                leading: const Icon(Icons.photo_library),
                title: const Text("Gallery"),
                onTap: () async {

                },
              ),
            ],
          );
        }
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: GestureDetector(
          onTap: () {
            _showDialog();
          },
          child: const Text(
            '\n点击显示弹窗一\n',
          ),
        ),
      ),
    );
  }
}

PopupMenuButton

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  var items = <String>["AA", "BB", "CC", "DD", "FF"];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        backgroundColor: Colors.greenAccent,
        actions: <Widget>[
          PopupMenuButton<String>(
            itemBuilder: (BuildContext context) {
              return _getItemBuilder2();
            },
            icon: const Icon(Icons.access_alarm),
            onSelected: (value) {
              debugPrint(value);
            },
            onCanceled: () {},
            offset: const Offset(200, 100),
          )
        ],
      ),
      body: const Center(),
    );
  }

  List<PopupMenuEntry<String>> _getItemBuilder() {
    return items
        .map((item) => PopupMenuItem<String>(
              value: item,
              child: Text(item),
            ))
        .toList();
  }

  List<PopupMenuEntry<String>> _getItemBuilder2() {
    return <PopupMenuEntry<String>>[
      const PopupMenuItem<String>(
        value: "1",
        child: ListTile(
          leading: Icon(Icons.share),
          title: Text('分享'),
        ),
      ),
      const PopupMenuDivider(), //分割线
      const PopupMenuItem<String>(
        value: "2",
        child: ListTile(
          leading: Icon(Icons.settings),
          title: Text('设置'),
        ),
      ),
    ];
  }
}
明确 Flutter 中 dialog 的基本特性
  • Flutterdialog 实际上是一个由 route 直接切换显示的页面,所以使用 Navigator.of(context) 的 push、pop(xx) 方法进行显示、关闭、返回数据
  • Flutter 中有两种风格的 dialog
    • showDialog() 启动的是 material 风格的对话框
    • showCupertinoDialog() 启动的是 ios 风格的对话框
  • Flutter 中有两种样式的 dialog
    • SimpleDialog 使用多个 SimpleDialogOption 为用户提供了几个选项
    • AlertDialog 一个可选标题 title 和一个可选列表的 actions 选项

 showDialog 方法讲解

Future<T> showDialog<T>({
  @required BuildContext context,
  bool barrierDismissible = true,
  @Deprecated(
    'Instead of using the "child" argument, return the child from a closure '
    'provided to the "builder" argument. This will ensure that the BuildContext '
    'is appropriate for widgets built in the dialog.'
  ) Widget child,
  WidgetBuilder builder,
}) {
    .......
}
  • context 上下文对象
  • barrierDismissible 点外面是不是可以关闭,默认是 true 可以关闭的
  • builder 是 widget 构造器
  • FlatButton 标准 AlertDialog 中的按钮必须使用这个类型
  • Navigator.of(context).pop(); 对话框内关闭对话框

 AlertDialog

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  void _showDialog() {
    // 定义对话框
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (context) {
        return AlertDialog(
          title: const Text("这里是测试标题"),
          actions: <Widget>[
            GestureDetector(
              child: const Text("删除"),
              onTap: () {
                debugPrint("删除");
                Navigator.of(context).pop();
              },
            ),
            GestureDetector(
              child: const Text("取消"),
              onTap: () {
                debugPrint("取消");
                Navigator.of(context).pop();
              },
            ),
          ],
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: GestureDetector(
          onTap: () {
            _showDialog();
          },
          child: const Text(
            '\n点击显示弹窗一\n',
          ),
        ),
      ),
    );
  }
}
自定义对话框

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  var num = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
            child: GestureDetector(
      onTap: () {
        showDialog(
            context: context,
            builder: (context) {
              return TestDialog();
            });
      },
      child: const Text(
        '\n点击显示弹窗一\n',
      ),
    )));
  }
}

class TestDialog extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return TestDialogState();
  }
}

class TestDialogState extends State<TestDialog> {
  var num = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Colors.transparent,
        body: Center(child: Container(
          color: Colors.greenAccent,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Text(
                num.toString(),
                style: const TextStyle(decoration: TextDecoration.none),
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  GestureDetector(
                    child: Text("+"),
                    onTap: () {
                      setState(() {
                        num++;
                      });
                    },
                  ),
                  GestureDetector(
                    child: Text("-"),
                    onTap: () {
                      setState(() {
                        num--;
                      });
                    },
                  ),
                ],
              ),
            ],
          ),
          width: 100,
          height: 200,
        ),));
  }
}

SimpleDialog

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  void _showDialog() {
    // 定义对话框
    showDialog(
        context: context,
        builder: (context) {
          return SimpleDialog(
            title: new Text("SimpleDialog"),
            children: <Widget>[
              new SimpleDialogOption(
                child: new Text("SimpleDialogOption One"),
                onPressed: () {
                  Navigator.of(context).pop("SimpleDialogOption One");
                },
              ),
              new SimpleDialogOption(
                child: new Text("SimpleDialogOption Two"),
                onPressed: () {
                  Navigator.of(context).pop("SimpleDialogOption Two");
                },
              ),
              new SimpleDialogOption(
                child: new Text("SimpleDialogOption Three"),
                onPressed: () {
                  Navigator.of(context).pop("SimpleDialogOption Three");
                },
              ),
            ],
          );
        });

  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: GestureDetector(
          onTap: () {
            _showDialog();
          },
          child: const Text(
            '\n点击显示弹窗一\n',
          ),
        ),
      ),
    );
  }
}

自定义ios风格对话框

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  void showCupertinoDialog() {
    var dialog = CupertinoAlertDialog(
      content: Text(
        "你好,我是你苹果爸爸的界面",
        style: TextStyle(fontSize: 20),
      ),
      actions: <Widget>[
        CupertinoButton(
          child: Text("取消"),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
        CupertinoButton(
          child: Text("确定"),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
      ],
    );

    showDialog(context: context, builder: (_) => dialog);
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: GestureDetector(
          onTap: () {
            showCupertinoDialog();
          },
          child: const Text(
            '\n点击显示弹窗一\n',
          ),
        ),
      ),
    );
  }
}

自定义对话框注意事项

  • 自定义的 dialog 要是太长了超过屏幕长度了,请在外面加一个可以滚动的 SingleChildScrollView
  • 自定义的 dialog 要是有 ListView 的话,必须在最外面加上一个确定宽度和高度的 Container,要不会报错,道理和上面的那条一样的

案例 切换到分支 flutter_custom_widget

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/491058.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

rabbitmq-c 程序实现客户端服务端

安装mq https://blog.csdn.net/zl_momomo/article/details/82986368 需要安裝rabbitmq-server 开启rabbitmq服务 systemctl start rabbitmq-server systemctl enable rabbitmq-server. 客户端 amqp_sendstring.c include <stdint.h> #include <stdio.h> #incl…

访问二维数组本质

先从一维数组讲起 int main() {int arr[5] { 1,2,3,4,5 };for (int i 0; i < 5; i) {printf("%d",arr[i]); //对数组进行访问}return 0; } 其实 arr [ i ] * (arr i) 这两个是完全相等的&#xff0c;在c语言指针&#xff08;1&#xff09;8.数组名与 …

STM32F103 CubeMX 使用USB生成键盘设备

STM32F103 CubeMX 使用USB生成键盘设备 基础信息HID8个数组各自的功能 生成代码代码编写添加申明信息main 函数编写HID 修改1. 修改报文描述符2 修改 "usbd_hid.h" 中的申明文件 基础信息 软件版本&#xff1a; stm32cubmx&#xff1a;6.2 keil 5 硬件&#xff1a;…

Redis中的事件(三)

时间事件 事件的调度与执行 因为服务器中同时存在文件事件和时间事件两种事件类型&#xff0c;所以服务器必须对这两种事件进行调度&#xff0c;决定何时应该处理文件事件&#xff0c;何时有应该处理时间事件&#xff0c;以及花多少事件来处理它们等等。事件的调度和执行由ae…

uniApp中使用小程序XR-Frame创建3D场景(2)加载模型

上篇文章讲述了如何将XR-Frame作为子组件集成到uniApp中使用&#xff0c;只完成了简单的环境搭建&#xff0c;这篇文章讲解如何加载3D模型。 1 加入模型加载标签 在XR-Frame框架中&#xff0c;加载资源都是在wxml文件的标签中实现的。下面是wxml中完整的代码 index.wxml &l…

(二)Eureka服务搭建,服务注册,服务发现

1.Eureka注册中心 假如我们的服务提供者user-service部署了多个实例&#xff0c;如图&#xff1a; 存在几个问题&#xff1a; order-service在发起远程调用的时候&#xff0c;该如何得知user-service实例的ip地址和端口&#xff1f;有多个user-service实例地址&#xff0c;…

手机和键盘的数字键盘排序为什么是不同的?

不知道你有没有注意有一个问题。我们的手机输入法中的数字键盘&#xff0c;电脑上通用的数字键盘&#xff0c;计算器上的数字键盘等排序是不同的&#xff0c;从观察者角度看&#xff0c;0-9的数字排列有从上到下的排列&#xff0c;还有从下到上的排列。为什么会出现不同的排列方…

HWOD:句子逆序

一、题目 描述 将一个英文语句以单词为单位逆序排放。例如I am a boy逆序排放后为boy a am I。所有单词之间用一个空格隔开。语句中除了英文字母外&#xff0c;不再包含其他字符。 数据范围 输入的字符串长度满足 1<n<1000 输入 输入一个英文语句&#xff0c;每个…

【电力监控保护】AM5SE-IS防孤岛保护装置/35kV、10kV、380V分布式光伏并网供电/什么是孤岛效应/孤岛效应的危害

什么是孤岛效应&#xff01;&#xff01;&#xff01; 安科瑞薛瑶瑶18701709087 在电力系统中&#xff0c;孤岛效应指的是当电网突然断电时&#xff0c;并网光伏发电系统仍然保持对电网中部分线路的供电状态。这种情况下&#xff0c;这些线路与其他电网断开&#xff0c;形成了…

HarmonyOS页面布局方式

Column&Row组件的使用 1 概述 一个丰富的页面需要很多组件组成&#xff0c;那么&#xff0c;我们如何才能让这些组件有条不紊地在页面上布局呢&#xff1f;这就需要借助容器组件来实现。 容器组件是一种比较特殊的组件&#xff0c;它可以包含其他的组件&#xff0c;而且…

亚马逊美国站CPC认证婴儿门栏和围栏安全标准cpsc办理

美国ASTM F1004-19认证属于婴幼儿门栏和围栏安全标准 ASTM F1004-19婴幼儿门栏和围栏安全标准 2020年7月6日&#xff0c;美国消费品安全委员会发布了最终法规16 CFR 1239&#xff0c;为婴幼儿门栏和围栏建立了安全标准。该法规合并及修订了最新版本的ASTM F1004-19《婴幼儿扩展…

【分布式】——降级熔断限流

降级&熔断&限流 ⭐⭐⭐⭐⭐⭐ Github主页&#x1f449;https://github.com/A-BigTree 笔记仓库&#x1f449;https://github.com/A-BigTree/tree-learning-notes 个人主页&#x1f449;https://www.abigtree.top ⭐⭐⭐⭐⭐⭐ 如果可以&#xff0c;麻烦各位看官顺手点…

API网关-Apisix路由配置教程(数据编辑器方式)

文章目录 前言一、端口修改1. apisix 端口修改2. dashboard 端口修改3. 登录密码修改 二、常用插件介绍1. 常用转换插件1.1 proxy-rewrite插件1.1.1 属性字段1.1.2 配置示例 2. 常用认证插件2.1 key-auth插件2.1.1 消费者端字段2.1.2 路由端字段2.1.3 配置示例 2.2 basic-auth插…

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记11:数字电位器MCP4017

系列文章目录 嵌入式|蓝桥杯STM32G431&#xff08;HAL库开发&#xff09;——CT117E学习笔记01&#xff1a;赛事介绍与硬件平台 嵌入式|蓝桥杯STM32G431&#xff08;HAL库开发&#xff09;——CT117E学习笔记02&#xff1a;开发环境安装 嵌入式|蓝桥杯STM32G431&#xff08;…

高速行者,5G工业路由器助力车联网无缝通信

随着5G技术的飞速发展&#xff0c;智能制造正迎来一个全新的时代。5G工业路由器作为车联网的核心设备&#xff0c;正在发挥着关键的作用。它不仅提供高速稳定的网络连接&#xff0c;还支持大规模设备连接和高密度数据传输&#xff0c;为车辆之间的实时通信和信息交换提供了强有…

GitLab更新失败(CentOS)

使用yum更新GitLab&#xff0c;出现如下错误提示&#xff1a; Error: Failed to download metadata for repo gitlab_gitlab-ce: repomd.xml GPG signature verification error: Bad GPG signature 编写如下脚本&#xff1a; for pubring in /var/cache/dnf/gitlab_gitlab-?…

java Web会议信息管理系统 用eclipse定制开发mysql数据库BS模式java编程jdbc

一、源码特点 jsp 会议信息管理系统是一套完善的web设计系统&#xff0c;对理解JSP java SERLVET mvc编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,eclipse开发&#xff0c;数据库为Mysql5.0&am…

react native

简介 React Native 就是使用React和应用平台的原生功能来构建 Android 和 iOS 应用的开源框架。在 Android 和 iOS 开发中&#xff0c;一个视图是 UI 的基本组成部分&#xff0c;React 组件通过 JavaScript 来调用这些视图。可以构建自己的 Native Components(原生组件)&#…

智慧体育场馆的优势都有哪些?

体育场馆作为体育产业和事业发展的重要载体&#xff0c;全民对健康和运动的需求越来越大&#xff0c;体育馆的需求也更大。而以前的体育场馆管理不仅人工成本高&#xff0c;人民的使用和消费也不方便。因此智慧体育馆的出现大大降低了运营人力成本及现金管理风险&#xff0c;大…

Jmeter脚本优化——随机函数

线程组下有 2 个请求的参数中均使用到相同的参数&#xff0c;在进行参数化时&#xff0c;想 要每个请求使用不同的取值。 &#xff08; 1 &#xff09; 线程组设置如下 &#xff08; 2 &#xff09; 线程组下添加加购物车请求&#xff0c;请求传参包含商品 id &#xff08;…