34 lines
1.1 KiB
Dart
34 lines
1.1 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
extension TextExt on Text {
|
|
/// Single-line width as rendered in [context] (honours the text scaler).
|
|
/// Memoised: chat bubbles measure the same few names and times over and
|
|
/// over, and every measurement is a full paragraph layout.
|
|
double measuredWidth(BuildContext context) {
|
|
final scaler = MediaQuery.textScalerOf(context);
|
|
final key = (data, style, scaler);
|
|
final cached = _widthCache[key];
|
|
if (cached != null) return cached;
|
|
final painter = TextPainter(
|
|
text: TextSpan(text: data, style: style),
|
|
maxLines: 1,
|
|
textDirection: TextDirection.ltr,
|
|
textScaler: scaler,
|
|
)..layout();
|
|
final width = painter.width;
|
|
painter.dispose();
|
|
if (_widthCache.length >= 512) _widthCache.clear();
|
|
return _widthCache[key] = width;
|
|
}
|
|
}
|
|
|
|
final Map<(String?, TextStyle?, TextScaler), double> _widthCache = {};
|
|
|
|
/// Returns the first non-empty (after trim) entry, or '' if none match.
|
|
String firstNonEmpty(List<String?> values) {
|
|
for (final v in values) {
|
|
if (v != null && v.trim().isNotEmpty) return v;
|
|
}
|
|
return '';
|
|
}
|