Flutter 组件抽取:日期(DatePicker)、时间(TimePicker)弹窗选择器【仿照】

news2024/11/14 15:29:53

简介

仿照《Flutter 仿ios自定义一个DatePicker》实行的日期弹窗选择器(DatePicker)、时间弹窗选择器(TimePicker)

效果

在这里插入图片描述

范例

class _TestPageState extends State<TestPage> {
  
  void initState() {
    super.initState();
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Picker')),
      body: SingleChildScrollView(
        child: Column(
          children: [
            GestureDetector(
              child: Container(
                alignment: Alignment.center,
                width: 160,
                height: 60,
                child: const Text('日期选择(年月日)'),
              ),
              onTap: () {
                DatePicker.show(
                  context,
                  startDate: DateTime(2022, 2, 2),
                  selectedDate: DateTime(2023, 3, 3),
                  endDate: DateTime(2025, 5, 5),
                  onSelected: (date) {
                    MsgUtil.toast(date.toString());
                  },
                );
              },
            ),
            GestureDetector(
              child: Container(
                alignment: Alignment.center,
                width: 160,
                height: 60,
                child: const Text('日期选择(年月)'),
              ),
              onTap: () {
                DatePicker.show(
                  context,
                  hideDay: true,
                  startDate: DateTime(2022, 2),
                  selectedDate: DateTime(2023, 3),
                  endDate: DateTime(2025, 5),
                  onSelected: (date) {
                    MsgUtil.toast(date.toString());
                  },
                );
              },
            ),
            GestureDetector(
              child: Container(
                alignment: Alignment.center,
                width: 160,
                height: 60,
                child: const Text('时间选择(时分秒)'),
              ),
              onTap: () {
                TimePicker.show(
                  context,
                  startTime: TimeData(11, 11, 11),
                  selectedTime: TimeData(15, 15, 15),
                  endTime: TimeData(22, 22, 22),
                  onSelected: (time) {
                    MsgUtil.toast(time.toString());
                  },
                );
              },
            ),
            GestureDetector(
              child: Container(
                alignment: Alignment.center,
                width: 160,
                height: 60,
                child: const Text('时间选择(时分)'),
              ),
              onTap: () {
                TimePicker.show(
                  context,
                  hideSecond: true,
                  startTime: TimeData(11, 11),
                  selectedTime: TimeData(15, 15),
                  endTime: TimeData(22, 22),
                  onSelected: (time) {
                    MsgUtil.toast(time.toString());
                  },
                );
              },
            ),
          ],
        ),
      ),
    );
  }
}

说明(DatePicker)

1、支持选中日期(selectedDate)、开始日期(startDate)、结束日期(endDate)的配置
2、支持“年月日”的选择,也支持“年月”的选择

代码(DatePicker)

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

typedef OnSelected = Function(DateTime date);

class DatePicker extends StatefulWidget {
  static void show(
    BuildContext context, {
    DateTime? startDate,
    DateTime? endDate,
    DateTime? selectedDate,
    bool hideDay = false,
    Function()? onCancel,
    required OnSelected onSelected,
  }) async {
    showModalBottomSheet(
      context: context,
      backgroundColor: Colors.transparent,
      builder: (BuildContext context) {
        return ClipRRect(
          borderRadius: const BorderRadius.only(
            topLeft: Radius.circular(8),
            topRight: Radius.circular(8),
          ),
          child: DatePicker._(
            selectedDate: selectedDate,
            startDate: startDate,
            endDate: endDate,
            onSelected: onSelected,
            hideDay: hideDay,
          ),
        );
      },
    ).then((value) => onCancel?.call());
  }

  const DatePicker._({
    this.selectedDate,
    this.startDate,
    this.endDate,
    this.hideDay = false,
    required this.onSelected,
  });

  final DateTime? selectedDate;
  final DateTime? startDate;
  final DateTime? endDate;
  final bool hideDay;
  final OnSelected onSelected;

  
  State createState() => _DatePickerState();
}

class _DatePickerState extends State<DatePicker> {
  late FixedExtentScrollController yearScrollController;
  late FixedExtentScrollController monthScrollController;
  late FixedExtentScrollController dayScrollController;

  List<String> yearList = []; // 年数组
  List<String> monthList = []; // 月数组
  List<String> dayList = []; // 天数组

  int yearIndex = 0; // 年的索引
  int monthIndex = 0; // 月的索引
  int dayIndex = 0; //天的索引

  late DateTime startDate;
  late DateTime endDate;
  late DateTime selectedDate;

  final double itemExtent = 44;

  /// 初始化数据
  void initData() {
    // 初始化年份数
    for (int i = startDate.year; i <= endDate.year; i++) {
      yearList.add(i.toString());
    }
    int selectYear = selectedDate.year;
    int selectMonth = selectedDate.month;
    // 初始化月份数
    monthList = getMonthList(selectYear);
    // 初始化天数
    dayList = getDayList(selectYear, selectMonth);
    // 初始化时间索引
    final List uniqueYearList = Set.from(yearList).toList();
    final List uniqueMonthList = Set.from(monthList).toList();
    final List uniqueDayList = Set.from(dayList).toList();
    // 获取索引
    setState(() {
      yearIndex = uniqueYearList.indexOf("${selectedDate.year}");
      monthIndex = uniqueMonthList.indexOf("${selectedDate.month}");
      dayIndex = uniqueDayList.indexOf("${selectedDate.day}");
    });
    // 设置Picker初始值
    yearScrollController = FixedExtentScrollController(initialItem: yearIndex);
    monthScrollController = FixedExtentScrollController(initialItem: monthIndex);
    dayScrollController = FixedExtentScrollController(initialItem: dayIndex);
  }

  List<String> getMonthList(int selectYear) {
    List<String> monthList = [];
    if (selectYear == startDate.year) {
      for (int i = startDate.month; i <= 12; i++) {
        monthList.add(i.toString());
      }
    } else if (selectYear == endDate.year) {
      for (int i = 1; i <= endDate.month; i++) {
        monthList.add(i.toString());
      }
    } else {
      for (int i = 1; i <= 12; i++) {
        monthList.add(i.toString());
      }
    }
    return monthList;
  }

  List<String> getDayList(int selectYear, int selectMonth) {
    List<String> dayList = [];
    int days = getDayCount(selectYear, selectMonth);
    if (selectYear == startDate.year && selectMonth == startDate.month) {
      for (int i = startDate.day; i <= days; i++) {
        dayList.add(i.toString());
      }
    } else if (selectYear == endDate.year && selectMonth == endDate.month) {
      for (int i = 1; i <= endDate.day; i++) {
        dayList.add(i.toString());
      }
    } else {
      for (int i = 1; i <= days; i++) {
        dayList.add(i.toString());
      }
    }
    return dayList;
  }

  int getDayCount(int year, int month) {
    int dayCount = DateTime(year, month + 1, 0).day;
    return dayCount;
  }

  /// 选中年月后更新天
  void updateDayList() {
    int year = int.parse(yearList[yearIndex]);
    int month = int.parse(monthList[monthIndex]);
    setState(() {
      dayIndex = 0;
      dayList = getDayList(year, month);
      if (dayScrollController.positions.isNotEmpty) {
        dayScrollController.jumpTo(0);
      }
    });
  }

  /// 选中年后更新月
  void updateMonthList() {
    int selectYear = int.parse(yearList[yearIndex]);
    setState(() {
      monthIndex = 0;
      monthList = getMonthList(selectYear);
      if (monthScrollController.positions.isNotEmpty) {
        monthScrollController.jumpTo(0);
      }
    });
  }

  
  void initState() {
    super.initState();
    startDate = widget.startDate ?? DateTime(1970, 1, 1);
    endDate = widget.endDate ?? DateTime(2099, 1, 1);
    selectedDate = widget.selectedDate ?? DateTime.now();
    if (endDate.difference(startDate).inSeconds < 0) {
      endDate = startDate;
    }
    if (selectedDate.difference(startDate).inSeconds < 0) {
      selectedDate = startDate;
    }
    if (selectedDate.difference(endDate).inSeconds > 0) {
      selectedDate = endDate;
    }
    initData();
  }

  
  void dispose() {
    yearScrollController.dispose();
    monthScrollController.dispose();
    dayScrollController.dispose();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Container(
            color: Colors.white,
            width: double.maxFinite,
            height: 200,
            child: Stack(
              alignment: AlignmentDirectional.center,
              children: [
                Container(
                  width: MediaQuery.of(context).size.width - 32,
                  height: itemExtent - 8,
                  decoration: BoxDecoration(
                    color: const Color(0xFFF1F1F1),
                    borderRadius: BorderRadius.circular(12),
                  ),
                ),
                Positioned(
                  left: 20,
                  right: 20,
                  top: 0,
                  bottom: 0,
                  child: Row(
                    mainAxisSize: MainAxisSize.min,
                    children: <Widget>[
                      Expanded(child: yearPickerView()),
                      Expanded(child: monthPickerView()),
                      widget.hideDay
                          ? const SizedBox()
                          : Expanded(child: dayPickerView()),
                    ],
                  ),
                ),
              ],
            ),
          ),
          Container(
            color: Colors.white,
            height: 68,
            padding: const EdgeInsets.only(left: 16, right: 16),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                Expanded(
                  child: TextButton(
                    child: const Text('取 消'),
                    onPressed: () {
                      Navigator.pop(context, false);
                    },
                  ),
                ),
                const SizedBox(width: 12),
                Expanded(
                  child: TextButton(
                    child: const Text('确 定'),
                    onPressed: () {
                      Navigator.pop(context, true);
                      widget.onSelected.call(DateTime(
                        int.parse(yearList[yearIndex]),
                        int.parse(monthList[monthIndex]),
                        int.parse(dayList[dayIndex]),
                      ));
                    },
                  ),
                ),
              ],
            ),
          ),
          SizedBox(height: MediaQuery.of(context).padding.bottom),
        ],
      ),
    );
  }

  /// 年Picker
  Widget yearPickerView() {
    return buildPickerBorder(
      child: CupertinoPicker(
        scrollController: yearScrollController,
        looping: false,
        selectionOverlay: const Center(),
        onSelectedItemChanged: (index) {
          setState(() {
            yearIndex = index;
          });
          updateMonthList();
          updateDayList();
        },
        itemExtent: itemExtent,
        children: buildYearWidget(),
      ),
    );
  }

  /// 月Picker
  Widget monthPickerView() {
    return buildPickerBorder(
      child: CupertinoPicker(
        scrollController: monthScrollController,
        looping: false,
        selectionOverlay: const Center(),
        onSelectedItemChanged: (index) {
          setState(() {
            monthIndex = index;
          });
          updateDayList();
        },
        itemExtent: itemExtent,
        children: buildMonthWidget(),
      ),
    );
  }

  /// 日Picker
  Widget dayPickerView() {
    return buildPickerBorder(
      child: CupertinoPicker(
        scrollController: dayScrollController,
        looping: false,
        selectionOverlay: const Center(),
        onSelectedItemChanged: (index) {
          setState(() {
            dayIndex = index;
          });
        },
        itemExtent: itemExtent,
        children: buildDayWidget(),
      ),
    );
  }

  /// 年Widget
  List<Widget> buildYearWidget() {
    List<Widget> widgets = [];
    for (var i = 0; i < yearList.length; i++) {
      widgets.add(
        Center(
          child: Text(
            '${yearList[i]}年',
            style: getTextStyle(i == yearIndex),
            maxLines: 1,
          ),
        ),
      );
    }
    return widgets;
  }

  /// 月Widget
  List<Widget> buildMonthWidget() {
    List<Widget> widgets = [];
    for (var i = 0; i < monthList.length; i++) {
      widgets.add(
        Center(
          child: Text(
            // monthList[i].padLeft(2, '0')
            '${monthList[i]}月',
            style: getTextStyle(i == monthIndex),
            maxLines: 1,
          ),
        ),
      );
    }
    return widgets;
  }

  /// 日Widget
  List<Widget> buildDayWidget() {
    List<Widget> widgets = [];
    for (var i = 0; i < dayList.length; i++) {
      widgets.add(
        Center(
          child: Text(
            // dayList[i].padLeft(2, '0')
            '${dayList[i]}日',
            style: getTextStyle(i == dayIndex),
            maxLines: 1,
          ),
        ),
      );
    }
    return widgets;
  }

  TextStyle getTextStyle(bool bold) {
    return TextStyle(
      color: Colors.black,
      fontSize: 20,
      height: 1,
      fontWeight: bold ? FontWeight.w600 : FontWeight.w400,
    );
  }

  Widget buildPickerBorder({required Widget child}) {
    return Stack(
      alignment: AlignmentDirectional.center,
      children: [
        /*Container(
          width: 90,
          height: itemExtent - 8,
          decoration: BoxDecoration(
            color: const Color(0xffEFEFF0),
            borderRadius: BorderRadius.circular(10),
          ),
        ),*/
        child,
      ],
    );
  }
}

说明(TimePicker)

1、支持选中时间(selectedtTime)、开始时间(starttTime)、结束时间(endtTime)的配置
2、支持“时分秒”的选择,也支持“时分”的选择
3、自定义时间数据类(TimeData)

代码(TimePicker)

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

typedef OnSelected = Function(TimeData time);
typedef PickerBuilder = Widget Function(BuildContext context);

class TimeData {
  final int hour;
  final int minute;
  final int second;

  TimeData(this.hour, [this.minute = 0, this.second = 0])
      : assert(hour >= 0 && hour <= 23),
        assert(minute >= 0 && minute <= 59),
        assert(second >= 0 && second <= 59);

  factory TimeData.now() {
    var now = DateTime.now();
    return TimeData(now.hour, now.minute, now.second);
  }

  bool precede(TimeData other) {
    return (hour < other.hour) ||
        (hour == other.hour && minute < other.minute) ||
        (hour == other.hour && minute == other.minute && second < other.second);
  }

  
  String toString() {
    return '$hour:$minute:$second';
  }
}

class TimePicker extends StatefulWidget {
  static void show(
    BuildContext context, {
    TimeData? startTime,
    TimeData? endTime,
    TimeData? selectedTime,
    bool hideSecond = false,
    Function()? onCancel,
    required OnSelected onSelected,
  }) async {
    showModalBottomSheet(
      context: context,
      backgroundColor: Colors.transparent,
      builder: (BuildContext context) {
        return ClipRRect(
          borderRadius: const BorderRadius.only(
            topLeft: Radius.circular(8),
            topRight: Radius.circular(8),
          ),
          child: TimePicker._(
            selectedTime: selectedTime,
            startTime: startTime,
            endTime: endTime,
            hideSecond: hideSecond,
            onSelected: onSelected,
          ),
        );
      },
    ).then((value) => onCancel?.call());
  }

  const TimePicker._({
    this.selectedTime,
    this.startTime,
    this.endTime,
    this.hideSecond = false,
    required this.onSelected,
  });

  final TimeData? selectedTime;
  final TimeData? startTime;
  final TimeData? endTime;
  final bool hideSecond;
  final OnSelected onSelected;

  
  State createState() => _TimePickerState();
}

class _TimePickerState extends State<TimePicker> {
  late FixedExtentScrollController hourScrollController;
  late FixedExtentScrollController minuteScrollController;
  late FixedExtentScrollController secondScrollController;

  List<String> hourList = [];
  List<String> minuteList = [];
  List<String> secondList = [];

  int hourIndex = 0;
  int minuteIndex = 0;
  int secondIndex = 0;

  late TimeData startTime;
  late TimeData endTime;
  late TimeData selectedTime;

  final double itemExtent = 44;

  /// 初始化数据
  void initData() {
    // 初始化时
    for (int i = startTime.hour; i <= endTime.hour; i++) {
      hourList.add(i.toString());
    }
    int selectHour = selectedTime.hour;
    int selectMinute = selectedTime.minute;
    // 初始化分
    minuteList = getMinuteList(selectHour);
    // 初始化秒
    secondList = getSecondList(selectHour, selectMinute);
    // 初始化时间索引
    final List uniqueHourList = Set.from(hourList).toList();
    final List uniqueMinuteList = Set.from(minuteList).toList();
    final List uniqueSecondList = Set.from(secondList).toList();
    // 获取索引
    setState(() {
      hourIndex = uniqueHourList.indexOf("${selectedTime.hour}");
      minuteIndex = uniqueMinuteList.indexOf("${selectedTime.minute}");
      secondIndex = uniqueSecondList.indexOf("${selectedTime.second}");
    });
    // 设置Picker初始值
    hourScrollController = FixedExtentScrollController(initialItem: hourIndex);
    minuteScrollController = FixedExtentScrollController(initialItem: minuteIndex);
    secondScrollController = FixedExtentScrollController(initialItem: secondIndex);
  }

  List<String> getMinuteList(int selectHour) {
    List<String> list = [];
    if (selectHour == startTime.hour) {
      for (int i = startTime.minute; i <= 59; i++) {
        list.add(i.toString());
      }
    } else if (selectHour == endTime.hour) {
      for (int i = 0; i <= endTime.minute; i++) {
        list.add(i.toString());
      }
    } else {
      for (int i = 0; i <= 59; i++) {
        list.add(i.toString());
      }
    }
    return list;
  }

  List<String> getSecondList(int selectHour, int selectMinute) {
    List<String> list = [];
    if (selectHour == startTime.hour && selectMinute == startTime.minute) {
      for (int i = startTime.second; i <= 59; i++) {
        list.add(i.toString());
      }
    } else if (selectHour == endTime.hour && selectMinute == endTime.minute) {
      for (int i = 0; i <= endTime.second; i++) {
        list.add(i.toString());
      }
    } else {
      for (int i = 0; i <= 59; i++) {
        list.add(i.toString());
      }
    }
    return list;
  }

  /// 选中时分后更新秒
  void updateSecondList() {
    int hour = int.parse(hourList[hourIndex]);
    int minute = int.parse(minuteList[minuteIndex]);
    setState(() {
      secondIndex = 0;
      secondList = getSecondList(hour, minute);
      if (secondScrollController.positions.isNotEmpty) {
        secondScrollController.jumpTo(0);
      }
    });
  }

  /// 选中时后更新分
  void updateMinuteList() {
    int selectHour = int.parse(hourList[hourIndex]);
    setState(() {
      minuteIndex = 0;
      minuteList = getMinuteList(selectHour);
      if (minuteScrollController.positions.isNotEmpty) {
        minuteScrollController.jumpTo(0);
      }
    });
  }

  
  void initState() {
    super.initState();
    DateTime now = DateTime.now();
    startTime = widget.startTime ?? TimeData(0, 0, 0);
    endTime = widget.endTime ?? TimeData(23, 59, 59);
    selectedTime = widget.selectedTime ?? TimeData(now.hour, now.minute, now.second);
    if (endTime.precede(startTime)) {
      endTime = startTime;
    }
    if (selectedTime.precede(startTime)) {
      selectedTime = startTime;
    }
    if (endTime.precede(selectedTime)) {
      selectedTime = endTime;
    }
    initData();
  }

  
  void dispose() {
    hourScrollController.dispose();
    minuteScrollController.dispose();
    secondScrollController.dispose();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Container(
            color: Colors.white,
            width: double.maxFinite,
            height: 200,
            child: Stack(
              alignment: AlignmentDirectional.center,
              children: [
                Container(
                  width: MediaQuery.of(context).size.width - 32,
                  height: itemExtent - 8,
                  decoration: BoxDecoration(
                    color: const Color(0xFFF1F1F1),
                    borderRadius: BorderRadius.circular(12),
                  ),
                ),
                Positioned(
                  left: 20,
                  right: 20,
                  top: 0,
                  bottom: 0,
                  child: Row(
                    mainAxisSize: MainAxisSize.min,
                    children: <Widget>[
                      Expanded(child: hourPickerView()),
                      Expanded(child: minutePickerView()),
                      widget.hideSecond
                          ? const SizedBox()
                          : Expanded(child: secondPickerView()),
                    ],
                  ),
                ),
              ],
            ),
          ),
          Container(
            color: Colors.white,
            height: 68,
            padding: const EdgeInsets.only(left: 16, right: 16),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                Expanded(
                  child: TextButton(
                    child: const Text('取 消'),
                    onPressed: () {
                      Navigator.pop(context, false);
                    },
                  ),
                ),
                const SizedBox(width: 12),
                Expanded(
                  child: TextButton(
                    child: const Text('确 定'),
                    onPressed: () {
                      Navigator.pop(context, true);
                      widget.onSelected.call(TimeData(
                        int.parse(hourList[hourIndex]),
                        int.parse(minuteList[minuteIndex]),
                        int.parse(secondList[secondIndex]),
                      ));
                    },
                  ),
                ),
              ],
            ),
          ),
          SizedBox(height: MediaQuery.of(context).padding.bottom),
        ],
      ),
    );
  }

  /// 时Picker
  Widget hourPickerView() {
    return buildPickerBorder(
      child: CupertinoPicker(
        scrollController: hourScrollController,
        looping: false,
        selectionOverlay: const Center(),
        onSelectedItemChanged: (index) {
          setState(() {
            hourIndex = index;
          });
          updateMinuteList();
          updateSecondList();
        },
        itemExtent: itemExtent,
        children: buildHourWidget(),
      ),
    );
  }

  /// 分Picker
  Widget minutePickerView() {
    return buildPickerBorder(
      child: CupertinoPicker(
        scrollController: minuteScrollController,
        looping: false,
        selectionOverlay: const Center(),
        onSelectedItemChanged: (index) {
          setState(() {
            minuteIndex = index;
          });
          updateSecondList();
        },
        itemExtent: itemExtent,
        children: buildMinuteWidget(),
      ),
    );
  }

  /// 秒Picker
  Widget secondPickerView() {
    return buildPickerBorder(
      child: CupertinoPicker(
        scrollController: secondScrollController,
        looping: false,
        selectionOverlay: const Center(),
        onSelectedItemChanged: (index) {
          setState(() {
            secondIndex = index;
          });
        },
        itemExtent: itemExtent,
        children: buildSecondWidget(),
      ),
    );
  }

  /// 时Widget
  List<Widget> buildHourWidget() {
    List<Widget> widgets = [];
    for (var i = 0; i < hourList.length; i++) {
      widgets.add(
        Center(
          child: Text(
            // hourList[i].padLeft(2, '0')
            '${hourList[i]}时',
            style: getTextStyle(i == hourIndex),
            maxLines: 1,
          ),
        ),
      );
    }
    return widgets;
  }

  /// 分Widget
  List<Widget> buildMinuteWidget() {
    List<Widget> widgets = [];
    for (var i = 0; i < minuteList.length; i++) {
      widgets.add(
        Center(
          child: Text(
            // minuteList[i].padLeft(2, '0')
            '${minuteList[i]}分',
            style: getTextStyle(i == minuteIndex),
            maxLines: 1,
          ),
        ),
      );
    }
    return widgets;
  }

  /// 秒Widget
  List<Widget> buildSecondWidget() {
    List<Widget> widgets = [];
    for (var i = 0; i < secondList.length; i++) {
      widgets.add(
        Center(
          child: Text(
            // secondList[i].padLeft(2, '0')
            '${secondList[i]}秒',
            style: getTextStyle(i == secondIndex),
            maxLines: 1,
          ),
        ),
      );
    }
    return widgets;
  }

  TextStyle getTextStyle(bool bold) {
    return TextStyle(
      color: Colors.black,
      fontSize: 20,
      height: 1,
      fontWeight: bold ? FontWeight.w600 : FontWeight.w400,
    );
  }

  Widget buildPickerBorder({required Widget child}) {
    return Stack(
      alignment: AlignmentDirectional.center,
      children: [
        /*Container(
          width: 90,
          height: itemExtent - 8,
          decoration: BoxDecoration(
            color: const Color(0xffEFEFF0),
            borderRadius: BorderRadius.circular(10),
          ),
        ),*/
        child,
      ],
    );
  }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java笔记_15(集合三)

Java笔记_15 一、创建不可变集合1.1、创建不可变集合的应用场景1.2、创建不可变集合的书写格式 二、Stream流2.1、体验Stream流2.2、Stream流的思想和获取Stream流2.3、Stream流的中间方法2.4、Stream流的终结方法2.5、收集方法collect 一、创建不可变集合 不可变集合&#xf…

山东省2023年春季高考技能测试电子技术类专业试题

注意事项 1.本试题为样题&#xff0c;实际测试试题与样题基本一致&#xff0c;不同场次试题电路装配要求会有变化&#xff0c;请考生仔细审题。 2.严禁考生私自送电&#xff0c;严禁带电操作&#xff08;通电调试除外&#xff09;。 3.考生要服从监考人员安排&#xff0c;遵…

【python入门篇】安装python教程

作者简介&#xff1a; 辭七七&#xff0c;目前大一&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a; Python入门&#xff0c;本专栏主要内容为Python的基础语法&#xff0c;Python中的选择循环语句…

【GPT】AutoGPT 安装使用完全教程

欢迎关注【youcans的GPT学习笔记】原创作品&#xff0c;火热更新中** 【GPT】AutoGPT 安装使用完全教程 【GPT】AutoGPT 安装使用完全教程1. AutoGPT 介绍1.1 AutoGPT 简介1.2 AutoGPT 的工作流程 2. 下载 AutoGPT 项目源码2.1 GitHub 下载项目源码2.2 网页下载稳定版源码 3. A…

数据结构(六)—— 二叉树(1)基础

文章目录 前言一、二叉树1.1 满二叉树1.2 完全二叉树1.3 二叉搜索树1.4 平衡二叉搜索树 二、二叉树的遍历2.1 深度优先遍历&#xff08;DFS&#xff09;2.2 广度优先遍历&#xff08;BFS&#xff09; 三、二叉树的代码定义 前言 提示&#xff1a;这里可以添加本文要记录的大概…

学习路线之白银5

init background 这个阶段你就要开始正式学习c了&#xff0c; 并且了解一些常用的git操作。 C 理解程序的编译流程&#xff0c;并映射到gcc和头文件的使用中。区分头文件&#xff0c; 源码等之间的关系理解编译工具的基本使用简单掌握基本的类和函数等常见语法&#xff0c;…

MapSet

在之前数据结构的学习中&#xff0c;对于数据的查找都是基于给定一个值&#xff0c;通过和序列中的关键字比较而实现的。因此这样的查找效率一般都是更依赖于比较的次数&#xff0c;像直接遍历或二分查找都是如此。而如果我们可以不经过任何比较&#xff0c;只是通过记录的关键…

外链跳转页功能分析与实现

一个大型的正规网站&#xff0c;增加一个 外链中转页 是有必要的。合理的交互设计&#xff0c;不仅能有效保障用户体验&#xff0c;又能帮助网站收集外链数据&#xff0c;优化运营管理。 目录 1、为什么使用跳转页面来管理外链 1.1、安全性 1.2、搜索引擎优化 1.3、外链数据…

JVM学习(九):堆

一、堆&#xff08;Heap&#xff09;的概述 一个JVM实例只存在一个堆内存&#xff0c;堆也是Java内存管理的核心区域。 Java堆区在JVM启动的时候即被创建&#xff0c;其空间大小也就确定了。是JVM管理的最大一块内存空间。同时&#xff0c;堆内存的大小是可以调节的。《Java虚拟…

ESP32-硬件IIC读取温湿度传感器SHT30

简介 esp32 使用硬件I2C读取温湿度传感器SHT30,例程基于EDP-IDF-4.4.X 的I2C Simple Example 例程修改 工程创建 打开 VSCODE ,通过 查看-- 命令面板&#xff08;快捷键CtrlShiftP&#xff09;&#xff0c;打开 ESP-IDF 的例程后&#xff0c;选择 i2c_simple 例程&#xff0…

深度学习卷积神经网络学习小结

————————————————————————————————————————————— 学习小结&#xff1a; 1&#xff09;深度学习综述&#xff1b;&#xff08;2&#xff09;对卷积神经网络&#xff08;CNN&#xff09;的认识&#xff1b;&#xff08;3&#xff0…

C语言中函数宏的三种封装方式详解

目录 ​编辑 1. 函数宏介绍 3. do{...}while(0) 方式 4. ({}) 方式 5. 总结 1. 函数宏介绍 函数宏&#xff0c;即包含多条语句的宏定义&#xff0c;其通常为某一被频繁调用的功能的语句封装&#xff0c;且不想通过函数方式封装来降低额外的弹栈压栈开销。 函数宏本质上为…

Winform从入门到精通(37)—FolderBrowserDialog(史上最全)

文章目录 前言1、Name2、Description3、RootFolder4、SelectedPath5、ShowNewFolderButton前言 当需要获取一个可以通过用户自由选择路径的时候,这时候就需要FolderBrowserDialog控件 1、Name 获取FolderBrowserDialog对象 2、Description 用于指示对话框的描述,如下: …

leetcode刷题(10)二叉树(4)

各位朋友们&#xff0c;大家五一劳动节快乐啊&#xff0c;在这里祝大家假期玩得愉快&#xff01;但是在玩耍的期间不要忘记了敲代码哦。今天我为大家分享的是二叉树的第四篇&#xff0c;废话不多说&#xff0c;我们一起来看看吧。 文章目录 二叉树的最近公共祖先题目要求做题思…

Stable Diffusion Controlnet V1.1 的14种基础标志用法

用于ControlNet和其他基于注入的SD控件的WebUI扩展。 针对 AUTOMATIC1111 的 Stable Diffusion web UI 网络用户界面的扩展&#xff0c;它可以让网络界面在原始的 Stable Diffusion 模型中添加 ControlNet 条件来生成图像。这种添加是实时的&#xff0c;不需要进行合并。 Con…

【openAI】Whisper如何高效语音转文字(详细教程)

文章目录 前言一、准备二、使用Whisper进行语音转文字三.Whisper转换结果分析总结 前言 语音转文字在许多不同领域都有着广泛的应用。以下是一些例子&#xff1a; 1.字幕制作&#xff1a;语音转文字可以帮助视频制作者快速制作字幕&#xff0c;这在影视行业和网络视频领域非常…

【软件下载】换新电脑记录下下载的软件时所需地址

1.idea https://www.jetbrains.com/zh-cn/idea/download/other.html 2.oracle官方&#xff08;下载jdk时找的&#xff09; https://www.oracle.com/ 3.jdk8 https://www.oracle.com/java/technologies/downloads/ 下拉找到jdk8 切换windows &#xff08;需要注册个oracle账…

TabError: inconsistent use of tabs and spaces in indentation

错误原因是tab制表符和空格混用了。从其他地方复制源码容易出现此错误 解决办法&#xff1a;把处于同级缩进的所有缩进修改统一 比较流行的几个编辑器都能标识tab和空格&#xff0c;比如我用的vscode 用鼠标框选不知道是tab还是空格的部分。 若是空格则显示为上图73行所示的点…

自动化运维工具一Ansible Roles实战

目录 一、Ansible Roles概述 1.1.roles官方的目录结构 1.2.Ansible Roles依赖关系 二、Ansible Roles案例实战 2.1.Ansible Roles NFS服务 2.2 Roles Memcached 2.3 Roles-rsync服务 一、Ansible Roles概述 之前介绍了 Playbook 的使用方法&#xff0c;对于批量任务的部…

C++程序设计——常见C++11新特性

一、列表初始化 1.C98中{}的初始化问题 在C98中&#xff0c;允许使用花括号{}对数组元素进行统一的列表初始化值设定&#xff0c;比如&#xff1a; 但是对于一些自定义类型&#xff0c;就无法使用这样的方式进行初始化了&#xff0c;比如&#xff1a; 就无法通过编译&#xff…