improved unknown file preview handling with probe failure fallbacks and switched to an explicit TabController in the share view to prevent build-time layout issues

This commit is contained in:
2026-05-13 20:28:30 +02:00
parent d970cfbe0c
commit 0fd42439e2
2 changed files with 104 additions and 69 deletions
+57 -45
View File
@@ -17,7 +17,19 @@ class QrShareView extends StatefulWidget {
State<QrShareView> createState() => _QrShareViewState();
}
class _QrShareViewState extends State<QrShareView> {
class _QrShareViewState extends State<QrShareView>
with SingleTickerProviderStateMixin {
// Owning the TabController explicitly (instead of DefaultTabController) is
// a workaround for a Flutter framework bug where TabBarView's
// didChangeDependencies issues a jumpToPage mid-build, whose scroll
// notification then calls setState on _TabStyle while the frame is still
// being built — only reproduces reliably with a bottomNavigationBar in the
// Scaffold underneath.
late final TabController _tabController = TabController(
length: 2,
vsync: this,
);
@override
void initState() {
ScreenBrightness.instance.setApplicationScreenBrightness(1.0);
@@ -26,6 +38,7 @@ class _QrShareViewState extends State<QrShareView> {
@override
void dispose() {
_tabController.dispose();
ScreenBrightness.instance.resetApplicationScreenBrightness();
super.dispose();
}
@@ -45,53 +58,52 @@ class _QrShareViewState extends State<QrShareView> {
}
@override
Widget build(BuildContext context) => DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
title: const Text('Teile die App'),
bottom: const TabBar(
tabs: [
Tab(icon: Icon(Icons.android_outlined), text: 'Android'),
Tab(icon: Icon(Icons.apple_outlined), text: 'iOS & iPadOS'),
],
),
),
body: const TabBarView(
children: [
AppSharePlatformView('Für Android', _androidUrl),
AppSharePlatformView('Für iOS & iPad', _iosUrl),
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: const Text('Teile die App'),
bottom: TabBar(
controller: _tabController,
tabs: const [
Tab(icon: Icon(Icons.android_outlined), text: 'Android'),
Tab(icon: Icon(Icons.apple_outlined), text: 'iOS & iPadOS'),
],
),
bottomNavigationBar: SafeArea(
child: Material(
color: Theme.of(context).colorScheme.surface,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Divider(height: 1),
Builder(
builder: (innerCtx) => ListTile(
leading: const Icon(Icons.share_outlined),
title: const Text('Per Link teilen'),
trailing: const Icon(Icons.arrow_right),
onTap: () => _shareLink(innerCtx),
),
),
body: TabBarView(
controller: _tabController,
children: const [
AppSharePlatformView('Für Android', _androidUrl),
AppSharePlatformView('Für iOS & iPad', _iosUrl),
],
),
bottomNavigationBar: SafeArea(
child: Material(
color: Theme.of(context).colorScheme.surface,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Divider(height: 1),
Builder(
builder: (innerCtx) => ListTile(
leading: const Icon(Icons.share_outlined),
title: const Text('Per Link teilen'),
trailing: const Icon(Icons.arrow_right),
onTap: () => _shareLink(innerCtx),
),
ListTile(
leading: const Icon(Icons.android_outlined),
title: const Text('Android-Link kopieren'),
trailing: const Icon(Icons.copy),
onTap: () => copyToClipboard(context, _androidUrl),
),
ListTile(
leading: const Icon(Icons.apple_outlined),
title: const Text('iOS-Link kopieren'),
trailing: const Icon(Icons.copy),
onTap: () => copyToClipboard(context, _iosUrl),
),
],
),
),
ListTile(
leading: const Icon(Icons.android_outlined),
title: const Text('Android-Link kopieren'),
trailing: const Icon(Icons.copy),
onTap: () => copyToClipboard(context, _androidUrl),
),
ListTile(
leading: const Icon(Icons.apple_outlined),
title: const Text('iOS-Link kopieren'),
trailing: const Icon(Icons.copy),
onTap: () => copyToClipboard(context, _iosUrl),
),
],
),
),
),