Flutter 自定义图片按钮,按下效果及按键音效

508 阅读1分钟
import 'package:flutter/material.dart';
import 'package:transparent_image/transparent_image.dart';
import 'package:just_audio/just_audio.dart';

class KarenButton extends StatefulWidget {
  final String image;
  //按钮类型,决定发音方式
  final String type;
  final Function onPressed;
  final double width;
  final double height;
  final Widget child;
  const KarenButton(
      {Key key,
      @required this.image,
      @required this.onPressed,
      @required this.width,
      @required this.height,
      this.child,
      this.type})
      : super(key: key);

  @override
  State<StatefulWidget> createState() {
    return _KarenButtonState();
  }
}
`
class _KarenButtonState extends State<KarenButton> {
  @override
  Widget build(BuildContext context) {
    return KarenImageButton(
      image: widget.image,
      onPressed: widget.onPressed,
      width: widget.width,
      height: widget.height,
      child: widget.child,
      type: widget.type,
    );
  }
}
/*
 * 图片 按钮
 */
class KarenImageButton extends StatefulWidget {
  //常规状态
  final String image;
  final String type;
  final Function onPressed;
  final double width;
  final double height;
  final Widget child;
  KarenImageButton({
    Key key,
    @required this.image,
    @required this.onPressed,
    @required this.width,
    @required this.height,
    this.type,
    this.child,
  }) : super(key: key);

  @override
  _KarenImageButtonState createState() {
    return _KarenImageButtonState();
  }
}

class _KarenImageButtonState extends State<KarenImageButton> {
  int pressedLong = 0;
  String asset = 'audios/click02.wav';
  final _playerClick = AudioPlayer();
  final Map<String, String> audioAssets = {
    'click': 'audios/click02.wav',
    'scroll': 'audios/scroll.m4a',
    'close': 'audios/close.m4a',
    'confirm': 'audios/confirm.m4a',
    'cancel': 'audios/cancel.m4a',
    'open': 'audios/open.m4a',
    'success': 'audios/success.mp3',
    'complete': 'audios/complete.m4a',
  };
  @override
  void initState() {
    super.initState();
    setState(() {
      asset = audioAssets.containsKey(widget.type)
          ? audioAssets[widget.type]
          : audioAssets['click'];
      _playerClick.setAsset(asset);
    });
  }

  Stream<bool> timer() {
    return Stream.periodic(Duration(milliseconds: 100), (i) {
      pressedLong -= 100;
      return pressedLong > 0 ? true : false;
    });
  }

  @override
  void dispose() {
    if (_playerClick != null) {
      _playerClick.dispose();
    }
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: widget.width,
      height: widget.height,
      child: OutlineButton(
        padding: EdgeInsets.all(0),
        borderSide: BorderSide.none,
        onPressed: () {
          _playerClick.stop();
          _playerClick.play();
          setState(() {
            pressedLong = 500;
          });
          Future.delayed(Duration(milliseconds: 300), () {
            Function.apply(widget.onPressed, []);
          });
        },
        child: new Container(
            width: widget.width,
            height: widget.height,
            alignment: Alignment.center,
            child: Stack(
              children: <Widget>[
                StreamBuilder<bool>(
                  stream: timer(),
                  builder:
                      (BuildContext context, AsyncSnapshot<bool> snapshot) {
                    if (snapshot.hasError) return Text('');
                    switch (snapshot.connectionState) {
                      case ConnectionState.none:
                        return Text('');
                      case ConnectionState.waiting:
                        return Center(
                            child: KarenImg(
                          img: widget.image,
                          width: widget.width,
                          height: widget.height,
                        ));
                      case ConnectionState.active:
                        return snapshot.data
                            ? Center(
                                child: KarenImg(
                                img: widget.image,
                                width: widget.width * 0.8,
                                height: widget.height * 0.8,
                              ))
                            : Center(
                                child: KarenImg(
                                  img: widget.image,
                                  width: widget.width,
                                  height: widget.height,
                                ),
                              );
                      case ConnectionState.done:
                        return Text('');
                    }
                    return null; // unreachable
                  },
                ),
                Center(
                  child: widget.child != null ? widget.child : Container(),
                ),
              ],
            )),
      ),
    );
  }
}

class KarenImg extends StatefulWidget {
  final String img;
  final double width;
  final double height;
  const KarenImg({Key key, @required this.img, this.height, this.width})
      : super(key: key);
  @override
  State<StatefulWidget> createState() {
    return _KarenImgState();
  }
}

class _KarenImgState extends State<KarenImg> {
  @override
  Widget build(BuildContext context) {
    return widget.img.indexOf('http') > -1
        ? new FadeInImage.memoryNetwork(
            placeholder: kTransparentImage,
            image: widget.img,
            height: widget.height,
            width: widget.width,
          )
        : !widget.img.isEmpty
            ? Image.asset(
                widget.img,
                width: widget.width,
                height: widget.height,
              )
            : Container();
  }
}