sliver_text 1.0.0
sliver_text: ^1.0.0 copied to clipboard
Text as a sliver. A drop-in Text equivalent for CustomScrollView that needs no SliverToBoxAdapter - with rich text, selection, semantics and gradient fill.
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:sliver_text/sliver_text.dart';
void main() => runApp(const MyApp());
const String _lorem =
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod '
'tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim '
'veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea '
'commodo consequat. Duis aute irure dolor in reprehenderit in voluptate.';
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'sliver_text example',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
),
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int _taps = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: SelectionArea(
child: CustomScrollView(
slivers: <Widget>[
const SliverAppBar.large(title: Text('sliver_text')),
_label('plain text, straight in the sliver list'),
const SliverPadding(
padding: EdgeInsets.symmetric(horizontal: 16),
sliver: SliverText(_lorem),
),
_label('gradient through the glyphs'),
const SliverPadding(
padding: EdgeInsets.symmetric(horizontal: 16),
sliver: SliverText(
'Gradient headline',
style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold),
gradient: LinearGradient(
colors: <Color>[Color(0xFF3F51B5), Color(0xFFE91E63)],
),
),
),
_label('maxLines with an ellipsis'),
const SliverPadding(
padding: EdgeInsets.symmetric(horizontal: 16),
sliver: SliverText(
_lorem,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
_label('rich text with a tappable span'),
SliverPadding(
padding: const EdgeInsets.symmetric(horizontal: 16),
sliver: SliverText.rich(
TextSpan(
text: 'Mixed ',
children: <InlineSpan>[
const TextSpan(
text: 'bold',
style: TextStyle(fontWeight: FontWeight.bold),
),
const TextSpan(text: ', '),
TextSpan(
text: 'tap me',
style: const TextStyle(
color: Colors.indigo,
decoration: TextDecoration.underline,
),
recognizer: TapGestureRecognizer()
..onTap = () => setState(() => _taps++),
),
TextSpan(text: ' (tapped $_taps times)'),
],
),
style: const TextStyle(fontSize: 20),
),
),
_label('semantics: reads as "ninety nine dollars"'),
const SliverPadding(
padding: EdgeInsets.symmetric(horizontal: 16),
sliver: SliverText(
r'$99',
style: TextStyle(fontSize: 32),
semanticsLabel: 'ninety nine dollars',
),
),
_label('everything above is selectable (SelectionArea)'),
const SliverToBoxAdapter(child: SizedBox(height: 48)),
],
),
),
);
}
Widget _label(String text) => SliverPadding(
padding: const EdgeInsets.fromLTRB(16, 32, 16, 8),
sliver: SliverText(
text.toUpperCase(),
style: TextStyle(
fontSize: 11,
letterSpacing: 1,
fontWeight: FontWeight.w700,
color: Theme.of(context).colorScheme.primary,
),
),
);
}