From 2b34f75056dc557ce3b8e43f345aa6c8a4a5ae4d Mon Sep 17 00:00:00 2001 From: lifegpc Date: Sat, 27 Jan 2024 10:44:43 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=87=AA=E9=80=82=E5=BA=94?= =?UTF-8?q?=E6=A0=87=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/components/fit_text.dart | 61 ++++++++++++++++++++++++++++++++++++ lib/viewer/single.dart | 12 +++++-- 2 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 lib/components/fit_text.dart diff --git a/lib/components/fit_text.dart b/lib/components/fit_text.dart new file mode 100644 index 0000000..ec7466e --- /dev/null +++ b/lib/components/fit_text.dart @@ -0,0 +1,61 @@ +import "package:flutter/material.dart"; + +class FitText extends StatefulWidget { + const FitText({ + Key? key, + required this.texts, + this.style, + this.separator = " ", + }) : super(key: key); + final List<(String, int)> texts; + final TextStyle? style; + final String separator; + + @override + State createState() => _FitText(); +} + +class _FitText extends State { + late List texts; + late List sizes; + + Size _textSize(String text, TextStyle? style) { + final TextPainter textPainter = TextPainter( + text: TextSpan(text: text, style: style), + maxLines: 1, + textDirection: TextDirection.ltr) + ..layout(minWidth: 0, maxWidth: double.infinity); + return textPainter.size; + } + + @override + void initState() { + super.initState(); + final tmp = widget.texts.map((e) => e.$2).toSet().toList() + ..sort((b, a) => a.compareTo(b)); + sizes = []; + texts = []; + for (final i in tmp) { + final text = widget.texts + .where((e) => e.$2 >= i) + .map((e) => e.$1) + .join(widget.separator); + texts.add(text); + sizes.add(_textSize(text, widget.style).width); + } + } + + @override + Widget build(BuildContext context) { + if (texts.isEmpty) return Container(); + return LayoutBuilder(builder: (context, constraints) { + final double maxWidth = constraints.maxWidth; + for (int i = sizes.length - 1; i >= 0; i--) { + if (sizes[i] <= maxWidth) { + return Text(texts[i], style: widget.style); + } + } + return Text(texts[0], style: widget.style); + }); + } +} diff --git a/lib/viewer/single.dart b/lib/viewer/single.dart index 9e80d60..551fc6e 100644 --- a/lib/viewer/single.dart +++ b/lib/viewer/single.dart @@ -12,6 +12,7 @@ import 'package:photo_view/photo_view.dart'; import 'package:photo_view/photo_view_gallery.dart'; import '../api/file.dart'; import '../api/gallery.dart'; +import '../components/fit_text.dart'; import '../globals.dart'; final _log = Logger("SinglePageViewer"); @@ -191,6 +192,7 @@ class _SinglePageViewer extends State Widget _buildTopAppBar(BuildContext context) { if (!_showMenu) return Container(); + final theme = Theme.of(context); return Positioned( top: 0, left: 0, @@ -201,8 +203,14 @@ class _SinglePageViewer extends State context.canPop() ? context.pop() : context.go(_back); }, icon: const Icon(Icons.close)), - title: - Text("${_data!.meta.preferredTitle} - ${_pages![_index].name}"), + title: FitText( + texts: [ + (_data!.meta.preferredTitle, 0), + (_pages![_index].name, 1) + ], + style: theme.appBarTheme.titleTextStyle ?? + theme.textTheme.titleLarge, + separator: " - "), actions: [ buildThemeModeIcon(context), buildMoreVertSettingsButon(context),