辛集市网站建设_网站建设公司_UI设计_seo优化
2025/12/18 17:26:07 网站建设 项目流程
              Row(children: [Expanded(child: LayoutBuilder(builder:(BuildContext context, BoxConstraints constraints) =>IntlWidget(maxWidth: constraints.maxWidth,child: Text('你好啊啊封疆大吏你好你好啊啊封疆大吏你好啊啊封疆大吏啊啊封疆大吏',),),),),// SizedBox(//   width: 5,// ),// Spacer(),
                  SizedBox(width: 5,),IntlWidget(maxWidth: calculateTextWidth('你好啊啊你好啊啊',expandedText: '你好啊啊封疆大吏你好你好啊啊封疆大吏你好啊啊封疆大吏啊啊封疆大吏',spacingWidth: 5,maxWidth: MediaQuery.of(context).size.width,maxLines: 1),child: Text('你好啊啊你好啊啊',),),],),

滚动部件

import 'dart:math';import 'package:flutter/material.dart';/// ⚠️direction目前切换方向需要重新运行才会正常,不要代码动态控制方向切换
class IntlWidget extends StatefulWidget {final Widget child;/// 动画方向, horizontal时要设置maxWidth才有效, vertical时要设置maxHeight才有效
  final Axis direction;//// /// 固定宽// final double? width;//// /// 固定高// final double? height;/// 最大宽final double? maxWidth;/// 最大高final double? maxHeight;const IntlWidget({super.key,required this.child,this.direction = Axis.horizontal,// this.width,// this.height,this.maxWidth,this.maxHeight});@overrideState<IntlWidget> createState() => _IntlWidgetState();
}class _IntlWidgetState extends State<IntlWidget>with SingleTickerProviderStateMixin {GlobalKey _key = GlobalKey();AnimationController? _controller;Animation<double>? _animation;double? _autoWidth;set autoWidth(double value) {if (widget.maxWidth != null) {_autoWidth = min(value, widget.maxWidth!);} else {_autoWidth = value;}}double get autoWidth {// if (widget.width != null) {//   return widget.width!;// }return _autoWidth ?? 0;}double? _autoHeight;set autoHeight(double value) {if (widget.maxHeight != null) {_autoHeight = min(value, widget.maxHeight!);} else {_autoHeight = value;}}double get autoHeight {// if (widget.height != null) {//   return widget.height!;// }return _autoHeight ?? 0;}Size? _contentSize;/// 动画偏移值double offsetX = 0, offsetY = 0;/// 是否缩放bool scaleDown = false;/// 横向差值范围小于此值时做缩放final scaleDownValue = 6;@overridevoid initState() {super.initState();WidgetsBinding.instance.addPostFrameCallback((_) {final renderBox = _key.currentContext?.findRenderObject() as RenderBox?;if (renderBox != null) {final size = renderBox.size;checkAnimate(size);}});}@overrideWidget build(BuildContext context) {return Container(// color: Colors.red,
      width: autoWidth,height: autoHeight,child: scaleDown? FittedBox(fit: BoxFit.scaleDown,child: Container(key: _key,child: widget.child,),): Stack(// clipBehavior: Clip.none,
        children: [Positioned(top: offsetY,left: offsetX,// width: widget.direction == Axis.horizontal//     ? null//     : _autoWidth,//(widget.width ?? _autoWidth),// height: widget.direction == Axis.vertical//     ? null//     : _autoHeight,//(widget.height ?? _autoHeight),
              child: Container(key: _key,child: widget.child,))],),);}@overridevoid didUpdateWidget(covariant IntlWidget oldWidget) {if (oldWidget.direction != widget.direction) {//   direction = true;//   offsetY = 0;//   offsetX = 0;//   setState(() {});//   direction = false;//   setState(() {});
    }super.didUpdateWidget(oldWidget);WidgetsBinding.instance.addPostFrameCallback((_) {final renderBox = _key.currentContext?.findRenderObject() as RenderBox?;if (renderBox != null) {final size = renderBox.size;checkAnimate(size);}});}@overridevoid dispose() {_controller?.dispose();super.dispose();}checkAnimate(Size contentSize) {_contentSize = contentSize;// if (widget.direction == )double? startAnimateWidth = widget.maxWidth;// ?? widget.width;double? startAnimateHeight = widget.maxHeight;// ?? widget.height;// print('child 宽度: ${contentSize.width};;;$startAnimateWidth, 高度: ${contentSize.height};; $startAnimateHeight');if (widget.direction == Axis.horizontal &&startAnimateWidth != null &&contentSize.width > startAnimateWidth) {_controller?.stop();final animateValue = contentSize.width - startAnimateWidth;autoWidth = startAnimateWidth;autoHeight = contentSize.height;scaleDown = animateValue.abs() < scaleDownValue;offsetY = (autoHeight - contentSize.height) * 0.5;// print("开始动画 scaleDownValue = $scaleDownValue");if (scaleDown) {offsetX = 0;setState(() {});return;}// print("开始动画 scaleDown = $scaleDown");final animateSec = (animateValue / 10).ceil();_controller ??= AnimationController(vsync: this,);_controller?.duration = Duration(seconds: animateSec);_animation?.removeListener(_updateOffsetX);_animation?.removeListener(_updateOffsetY);_animation =Tween<double>(begin: 0.0, end: animateValue).animate(CurvedAnimation(parent: _controller!,curve: Curves.easeInOutSine,));_animation?.addListener(_updateOffsetX);// 启动动画_controller?.repeat(reverse: true,);} else if (widget.direction == Axis.vertical &&startAnimateHeight != null &&contentSize.height > startAnimateHeight) {_controller?.stop();final animateValue = contentSize.height - startAnimateHeight;autoWidth = contentSize.width;autoHeight = startAnimateHeight;scaleDown = animateValue.abs() < scaleDownValue;offsetX = (autoWidth - contentSize.width) * 0.5;// print("开始动画 vertical scaleDownValue = $scaleDownValue");if (scaleDown) {offsetY = 0;setState(() {});_controller?.stop();return;}// print("开始动画 vertical scaleDown = $scaleDown");final animateSec = (animateValue / 4).ceil();_controller ??= AnimationController(vsync: this,);_controller?.duration = Duration(seconds: animateSec);_animation?.removeListener(_updateOffsetX);_animation?.removeListener(_updateOffsetY);_animation =Tween<double>(begin: 0.0, end: animateValue).animate(CurvedAnimation(parent: _controller!,curve: Curves.easeInOutSine,));_animation?.addListener(_updateOffsetY);// 启动动画_controller?.repeat(reverse: true,);} else {setState(() {autoWidth = contentSize.width;autoHeight = contentSize.height;offsetX = 0;offsetY = 0;});_controller?.stop();}}// 更新横向偏移void _updateOffsetX() {setState(() {offsetX = -_animation!.value;});}// 更新纵向偏移void _updateOffsetY() {setState(() {offsetY = -_animation!.value;});}
}

 

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询