flutter 每个控件都可以单独抽出来

一个布局可能会有很多组件 ,每个组件都可能是一个大功能,可能要用一大堆代码实现,这时候就可以把那个组件拆出来,单独放在一个类里面了。一个组件拆出来,放在一个类里面,单独展示的话就是全屏显示的一个组件,然后抽出来的时候就是设宽高,直接调用这个类。或者如果已经调好的就直接调用这个类
在这里插入图片描述
比如发布按钮和跳到顶部的按钮就可以拆分出来。

    return Scaffold(
        resizeToAvoidBottomInset: false,
        backgroundColor: Colors.transparent,
        body: Container(
            color: Colors.transparent,
            child: Stack(children: [
              RefreshConfiguration(
                  enableLoadingWhenFailed: true,
                  hideFooterWhenNotFull: true,
                  child: SmartRefresher(
                      enablePullDown: true,
                      enablePullUp: true,
                      controller: _refreshController,
                      onLoading: _onLoading,
                      onRefresh: _onRefresh,
                      footer: const ClassicFooter(
                          loadStyle: LoadStyle.ShowWhenLoading),
                      child: CustomScrollView(
                          controller: _scrollController,
                          slivers: <Widget>[
                            SliverToBoxAdapter(child: MomentBanner(controller)),
                            getMomentListView()
                          ]))),
              MomentBottomItem(showFastView, _scrollController),//两个控件都放在这个类里面面了,简洁了好多
            ])));

因为发布按钮是一个动画来的,所以也单独拆到一个类里面,实现的功能代码也放在这个类里面,清晰明了。怎么拆?可以单独跳转到那个动画按键界面,它是满屏的,居中的。同样道理,满屏变成宽70和高70。这跟原生的自定义view差不多,可以想象成70宽70高,然后装着一个自己定义的一个组件界面

Container(
                                  width: WidgetAdaptation.getWidth(70),
                                  height: WidgetAdaptation.getWidth(70),
                                  margin: EdgeInsets.only(
                                      bottom: WidgetAdaptation.getWidth(10)),
                                  child: const ReleaseDynamicAnimation(),
                                  alignment: Alignment.center)

MomentBottomItem类如下

import 'package:flutter/material.dart';
import 'package:social_im/camera_picker/constants/constants.dart';
import 'package:social_im/common/globalEventBus.dart';
import 'package:social_im/generated/l10n.dart';
import 'package:social_im/pages/dialog/ReleaseDynamicsAnimation.dart';
import 'package:social_im/pages/widget/splitLine.dart';
import 'package:social_im/utils/widgetAdaptation.dart';

///动态b底部控件
import '../../dialog/PostSeekingDialog.dart';

class MomentBottomItem extends StatefulWidget {
  bool showFastView = false;
  ScrollController scrollController;

  MomentBottomItem(this.showFastView, this.scrollController, {Key? key})
      : super(key: key);

  @override
  State<StatefulWidget> createState() => MomentBottomItemState();
}

class MomentBottomItemState extends State<MomentBottomItem> {
  List<AssetEntity> assetss = [];

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

  @override
  void dispose() {
    super.dispose();
  }

  ///调起相册
  releaseDynamic() async {
    //停掉发布动态按钮的动画
    EventBusUtil.fire(SendDynamicAnimationEvent(false));
    showDialog(
            context: context, builder: (context) => PostMomentSeekingDialog())
        .then((value) => EventBusUtil.fire(SendDynamicAnimationEvent(true)));
  }

  mySetState(callBack) {
    if (mounted) {
      setState(() {
        callBack();
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Positioned(
        right: WidgetAdaptation.getWidth(13),
        bottom: WidgetAdaptation.getWidth(50),
        child: Container(
            margin: EdgeInsets.only(right: WidgetAdaptation.getWidth(0)),
            child: Column(children: [
              Offstage(
                  offstage: !widget.showFastView,
                  child: GestureDetector(
                      onTap: () {
                        // _scrollController.position.pixels
                        widget.scrollController.jumpTo(0.0);
                      },
                      child: Image(
                          width: WidgetAdaptation.getWidth(45),
                          height: WidgetAdaptation.getWidth(45),
                          image: const AssetImage(
                              'assets/images/icon_dynamic_slide_up.png')))),
              Stack(
                  clipBehavior: Clip.none,
                  alignment: Alignment.bottomCenter,
                  children: [
                    GestureDetector(
                        onTap: () {
                          releaseDynamic();
                        },
                        child: Container(
                            margin: EdgeInsets.only(
                                top: WidgetAdaptation.getWidth(13)),
                            color: Colors.transparent,
                            height: WidgetAdaptation.getWidth(80),
                            width: WidgetAdaptation.getWidth(58))),
                    Stack(
                        alignment: Alignment.bottomCenter,
                        clipBehavior: Clip.none,
                        children: [
                          GestureDetector(
                              onTap: () {
                                releaseDynamic();
                              },
                              child: Container(
                                  width: WidgetAdaptation.getWidth(70),
                                  height: WidgetAdaptation.getWidth(70),
                                  margin: EdgeInsets.only(
                                      bottom: WidgetAdaptation.getWidth(10)),
                                  child: const ReleaseDynamicAnimation(),//发布按钮的实现在这里
                                  alignment: Alignment.center)),
                          Positioned(
                              bottom: -18,
                              child: GestureDetector(
                                  onTap: () {
                                    releaseDynamic();
                                  },
                                  child: ConstrainedBox(
                                      constraints: BoxConstraints(
                                          minHeight:
                                              WidgetAdaptation.getWidth(24),
                                          minWidth:
                                              WidgetAdaptation.getWidth(58)),
                                      child: Container(
                                          padding: const EdgeInsets.only(
                                              left: 14,
                                              right: 14,
                                              top: 2,
                                              bottom: 2),
                                          margin: EdgeInsets.only(
                                              bottom: WidgetAdaptation.getWidth(
                                                  10)),
                                          alignment: Alignment.center,
                                          decoration: BoxDecorationUtil()
                                              .setFillBoxDecorationImg(
                                                  'assets/images/bg_send_moment.png'),
                                          child: Text(S.current.post,
                                              style: const TextStyle(
                                                  color: Color(0xFF09DECB),
                                                  fontSize: 14))))))
                        ])
                  ])
            ])));
  }
}

ReleaseDynamicAnimation发布按钮的实现

import 'dart:async';

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

import '../../common/Global.dart';
import '../../common/backgroundWall.dart';
import '../../common/globalEventBus.dart';
import '../../utils/printUtil.dart';
import '../../utils/widgetAdaptation.dart';
import '../widget/splitLine.dart';

class ReleaseDynamicAnimation extends StatefulWidget{
  const ReleaseDynamicAnimation({Key? key}) : super(key: key);

  @override
  State<StatefulWidget> createState() =>ReleaseAnimation();
}

class ReleaseAnimation extends State<ReleaseDynamicAnimation> with TickerProviderStateMixin, WidgetsBindingObserver, RouteAware{
  final List<Widget> backdropAnimationList = [];
  ///背景动画控制器   ///背景动画控件集合
  final List<AnimationController> backdropControllerList = [];
  int playMilliseconds = 1500;
  int playTimeMilliseconds = 1500;
  late StreamSubscription<SendDynamicAnimationEvent> sendDynamicEvent;
  bool hasSelectTab=false;
  @override
  void initState() {
    WidgetsBinding.instance!.addObserver(this);
    sendDynamicEvent=EventBusUtil.listen((event) {

      if(event.isSelectTab==true&&!hasSelectTab){
        createBackdropAnimation(true);
      }else{
        createBackdropAnimation(false);
      }
      hasSelectTab=event.isSelectTab;
    });
    super.initState();
  }

  @override
  void dispose() {
    backdropAnimationList.clear();
    for (int i = 0; i < backdropControllerList.length; i++) {
      backdropControllerList[i].reset();
      backdropControllerList[i].dispose();
    }

    backdropControllerList.clear();
    super.dispose();
  }

  mySetState(callBack) {
    if (mounted) {
      setState(() {
        callBack();
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Stack(alignment: Alignment.center, children: [
      Stack(alignment: Alignment.center, children: backdropAnimationList),
      Container(
          width: WidgetAdaptation.getWidth(50),
          height: WidgetAdaptation.getWidth(50),
          alignment: Alignment.center,
          decoration: BoxDecorationUtil().setFillBoxDecorationImg(
              'assets/images/icon_send_moment_cir.png'),
          child: Container(
            margin: const EdgeInsets.only(right: 2),
              width: WidgetAdaptation.getWidth(26),
              height: WidgetAdaptation.getWidth(26),
              alignment: Alignment.center,
              decoration: BoxDecorationUtil().setFillBoxDecorationImg(
                  'assets/images/icon_send_moment_plane.png'),
             )),
    ]);
  }

  Animation<double> createItemAnimation(parent, double begin, double end,
      double beginCurve, double endCurve, curve) {
    Animation<double> animation =
    Tween<double>(begin: begin, end: end).animate(CurvedAnimation(
        parent: parent,
        curve: Interval(beginCurve, endCurve, //间隔,后40%的动画时间
            curve: curve)));
    return animation;
  }

  ///创建背景动画
  createBackdropAnimation(isPlayBackdropAnimation) {
    if (isPlayBackdropAnimation&&mounted) {
        AnimationController animationController =
        createBackdropController(playMilliseconds);
      backdropControllerList.add(animationController);

      Animation<double> backdropTransparentAnimation = createItemAnimation(
          animationController, 0.5, 1.0, 0.0, 0.5, Curves.linear);

      Animation<double> backdropTransparentAnimationTwo = createItemAnimation(
          animationController, 0.0, 1.0, 0.5, 0.9, Curves.linear);

      Animation<double> backdropHeightAnimation = createItemAnimation(
          animationController,
          WidgetAdaptation.getWidth(50),
          WidgetAdaptation.getWidth(80),
          0.0,
          1.0,
          Curves.linear);

      backdropAnimationList.add(AnimatedBuilder(
          animation: animationController,
          builder: (BuildContext context, Widget? child) {
            return Opacity(
                opacity: (backdropTransparentAnimation.value) -
                    (backdropTransparentAnimationTwo.value),
                child: BackgroundWall(
                  // width: backdropHeightAnimation.value,
                    height: backdropHeightAnimation.value,
                    radius: 5,
                    avtarUrl:
                    'assets/images/icon_send_moment_animation.png',
                    svgaAvtarUrl: Global.defBackImag));
          }));
      try {
        //动画页退出时,捕获可能发生的异常
        animationController.forward();
        // PrintUtil.prints('动画播放');
        mySetState(() {});
      } catch (e) {
        PrintUtil.prints('动画播放异常 $e');
        return;
      }

      // PrintUtil.prints('动画播放 $playTimeMilliseconds');
      Future.delayed(Duration(milliseconds: playTimeMilliseconds), () {
        if (isPlayBackdropAnimation && mounted && hasSelectTab) {
          createBackdropAnimation(true);
        }
      });
    } else {
      for (int i = 0; i < backdropControllerList.length; i++) {
        backdropControllerList[i].reset();
        backdropControllerList[i].dispose();
      }

      backdropControllerList.clear();
      backdropAnimationList.clear();
      mySetState(() {});
    }
  }

  AnimationController createBackdropController(milliseconds) {
    AnimationController animationController = AnimationController(
        duration: Duration(milliseconds: milliseconds), vsync: this);

    animationController.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        animationController.reset();
        animationController.dispose();
        if (backdropControllerList.contains(animationController)) {
          backdropControllerList.remove(animationController);
          backdropAnimationList.removeAt(0);
        }
      }
    });
    return animationController;
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值