buildContent method

  1. @override
Widget buildContent(
  1. BuildContext context,
  2. RefreshStatus? mode
)
override

Builds the content of the indicator.

Implementation

@override
Widget buildContent(BuildContext context, RefreshStatus? mode) {
  final ThemeData theme = Theme.of(context);
  final bool isDark = theme.brightness == Brightness.dark;
  final SmartRefresherThemeData refresherTheme = SmartRefresherTheme.of(
    context,
  );
  final Color accentColor = widget.color ??
      refresherTheme.primaryColor ??
      theme.colorScheme.primary;

  final Color fillColor = widget.glassColor ??
      (isDark
          ? Colors.black.withValues(alpha: 0.25 * _currentFillOpacity)
          : Colors.white.withValues(alpha: 0.18 * _currentFillOpacity));
  final Color glassBorder = widget.borderColor ??
      (isDark
          ? Colors.white.withValues(alpha: 0.15 * _currentFillOpacity)
          : Colors.white.withValues(alpha: 0.50 * _currentFillOpacity));

  final bool isRefreshing = mode == RefreshStatus.refreshing;
  final bool isIdle = mode == null || mode == RefreshStatus.idle;
  final bool showPanel = _dragProgress > 0.0 ||
      mode == RefreshStatus.canRefresh ||
      isRefreshing ||
      _isCompleted ||
      _isFailed;

  final double screenWidth = MediaQuery.sizeOf(context).width;
  final double pillWidth = math.min(screenWidth * 0.75, 320.0);

  Widget indicator;
  if (isRefreshing) {
    indicator = CupertinoActivityIndicator(color: accentColor);
  } else {
    indicator = CustomPaint(
      size: const Size(28.0, 28.0),
      painter: _ArcPainter(
        progress: _dragProgress,
        trackColor: Colors.white.withValues(alpha: 0.25),
        arcColor: accentColor,
      ),
    );
  }

  Widget textWidget = const SizedBox.shrink();
  if (widget.showText && _statusText.isNotEmpty && !isIdle) {
    textWidget = Padding(
      padding: const EdgeInsets.only(left: 10.0),
      child: Text(
        _statusText,
        style: TextStyle(
          color: Colors.white,
          fontSize: 13.0,
          fontWeight: FontWeight.w500,
          shadows: <Shadow>[
            Shadow(
              color: Colors.black.withValues(alpha: 0.30),
              blurRadius: 4.0,
            ),
          ],
        ),
      ),
    );
  }

  Widget pill = Container(
    width: pillWidth,
    height: 52.0,
    decoration: BoxDecoration(
      borderRadius: BorderRadius.circular(26.0),
      boxShadow: <BoxShadow>[
        BoxShadow(
          color: Colors.black.withValues(alpha: 0.12 * _currentFillOpacity),
          blurRadius: 12.0,
          offset: const Offset(0.0, 4.0),
        ),
      ],
    ),
    child: ClipRRect(
      borderRadius: BorderRadius.circular(26.0),
      child: Stack(
        fit: StackFit.expand,
        children: <Widget>[
          BackdropFilter(
            filter:
                ImageFilter.blur(sigmaX: _currentBlur, sigmaY: _currentBlur),
            child: const SizedBox.expand(),
          ),
          Container(
            decoration: BoxDecoration(
              color: fillColor,
              borderRadius: BorderRadius.circular(26.0),
              border: Border.all(color: glassBorder),
            ),
          ),
          Center(
            child: Row(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[indicator, textWidget],
            ),
          ),
        ],
      ),
    ),
  );

  pill = ScaleTransition(scale: _panelScaleAnimation, child: pill);

  if (_isCompleted || _isFailed) {
    pill = FadeTransition(
      opacity: Tween<double>(begin: 1.0, end: 0.0).animate(_dismissAnimation),
      child: pill,
    );
  }

  return SizedBox(
    height: widget.height,
    child: Center(
      child: Opacity(
        opacity:
            showPanel && !isIdle ? 1.0 : (_dragProgress > 0.0 ? 1.0 : 0.0),
        child: RepaintBoundary(child: pill),
      ),
    ),
  );
}