Flutter封装switch实践 2023-09-08 周五

2023-09-07  本文已影响0人  勇往直前888

简介

iOS原生开发的时候,Switch是一个很简单的控件,使用起来非常方便。
但是,到了Flutter中,关于Switch却遇到了许多的困惑,带来了一定的混乱。

Android风格的Switch

企业微信截图_8c91f97c-c65e-44b5-bdca-ab8447350875.png
Switch({
  Key? key,
  required bool value,
  required void Function(bool)? onChanged,
  Color? activeColor,
  Color? activeTrackColor,
  Color? inactiveThumbColor,
  Color? inactiveTrackColor,
  ImageProvider<Object>? activeThumbImage,
  void Function(Object, StackTrace?)? onActiveThumbImageError,
  ImageProvider<Object>? inactiveThumbImage,
  void Function(Object, StackTrace?)? onInactiveThumbImageError,
  MaterialStateProperty<Color?>? thumbColor,
  MaterialStateProperty<Color?>? trackColor,
  MaterialStateProperty<Color?>? trackOutlineColor,
  MaterialStateProperty<double?>? trackOutlineWidth,
  MaterialStateProperty<Icon?>? thumbIcon,
  MaterialTapTargetSize? materialTapTargetSize,
  DragStartBehavior dragStartBehavior = DragStartBehavior.start,
  MouseCursor? mouseCursor,
  Color? focusColor,
  Color? hoverColor,
  MaterialStateProperty<Color?>? overlayColor,
  double? splashRadius,
  FocusNode? focusNode,
  void Function(bool)? onFocusChange,
  bool autofocus = false,
})

iOS风格的Switch

企业微信截图_02ae9533-488e-4e2c-bb93-84d68f22a63a.png
CupertinoSwitch({
  Key? key,
  required bool value,
  required void Function(bool)? onChanged,
  Color? activeColor,
  Color? trackColor,
  Color? thumbColor,
  bool? applyTheme,
  Color? focusColor,
  FocusNode? focusNode,
  void Function(bool)? onFocusChange,
  bool autofocus = false,
  DragStartBehavior dragStartBehavior = DragStartBehavior.start,
})

是否保持状态?

实际上Switch不能保留状态,但是确实能将变化后的状态传出来。并且传出来值必定跟传入的value值相反

思路

参数设计

/// 模式1:给value参数,不保持状态,由父组件指定开关状态;
/// 模式2:不给value参数,自己记忆开关状态;
class PandaSwitch extends StatefulWidget {
  const PandaSwitch({
    Key? key,
    this.initialValue,
    this.value,
    this.onChanged,
    this.width,
    this.height,
    this.margin,
    this.padding,
  }) : super(key: key);

  final bool? initialValue;
  final bool? value;
  final void Function(bool)? onChanged;
  final double? width;
  final double? height;
  final EdgeInsetsGeometry? margin;
  final EdgeInsetsGeometry? padding;

  @override
  State<PandaSwitch> createState() => _PandaSwitchState();
}

具体实现

基类

由于要保存状态,响应点击的变化,所以选择StatefulWidget作为基类;

初始值

  @override
  void initState() {
    super.initState();

    /// 初始值由外部指定;不指定的话,给默认值false
    _isOn = widget.initialValue ?? false;
  }

模式确定

  @override
  Widget build(BuildContext context) {
    /// 如果外部指定了值,那么强制设定为外部值
    if (widget.value != null) {
      _isOn = widget.value!;
    }
    ///……
  }

界面实现

企业微信截图_77280fc2-14c4-46ea-a8de-86cfa35865b6.png

参考代码

import 'package:flutter/material.dart';
import 'package:pandabuy/r.dart';

/// 模式1:给value参数,不保持状态,由父组件指定开关状态;
/// 模式2:不给value参数,自己记忆开关状态;
class PandaSwitch extends StatefulWidget {
  const PandaSwitch({
    Key? key,
    this.initialValue,
    this.value,
    this.onChanged,
    this.width,
    this.height,
    this.margin,
    this.padding,
  }) : super(key: key);

  final bool? initialValue;
  final bool? value;
  final void Function(bool)? onChanged;
  final double? width;
  final double? height;
  final EdgeInsetsGeometry? margin;
  final EdgeInsetsGeometry? padding;

  @override
  State<PandaSwitch> createState() => _PandaSwitchState();
}

class _PandaSwitchState extends State<PandaSwitch> {
  late bool _isOn;

  @override
  void initState() {
    super.initState();

    /// 初始值由外部指定;不指定的话,给默认值false
    _isOn = widget.initialValue ?? false;
  }

  @override
  Widget build(BuildContext context) {
    /// 如果外部指定了值,那么强制设定为外部值
    if (widget.value != null) {
      _isOn = widget.value!;
    }

    var imageName = _isOn ? R.assetsImgSwitchOn : R.assetsImgSwitchOff;
    return GestureDetector(
      behavior: HitTestBehavior.opaque,
      onTap: () {
        setState(() {
          _isOn = !_isOn;
        });
        if (widget.onChanged != null) {
          widget.onChanged!(_isOn);
        }
      },
      child: Container(
        color: Colors.transparent,
        width: widget.width,
        height: widget.height,
        margin: widget.margin,
        padding: widget.padding,
        child: Center(
          child: Image.asset(imageName),
        ),
      ),
    );
  }
}

使用的例子

PandaSwitch(
  margin: EdgeInsets.only(left: 5.w),
  value: ((pi['unPackWeightSelect'] ==
          '1') ||
      (pi['unPackWeightSelect'] == '2')),
  onChanged: (value) {
    if (pi['unPackWeightSelect'] == '2') {
      return;
    }
    logic.unPackClick(pi, value);
  },
),
上一篇 下一篇

猜你喜欢

热点阅读