Flutter UI Widgets

Nov 9 2021 · Dart 2.14, Flutter 2.5, VS Code 1.61

Part 1: Flutter UI Widgets

09. Add Navigation & SliverAppBar

Episode complete

Play next episode

Next
About this episode

Leave a rating/review

See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 08. Style Your App with Themes Next episode: 10. Work with Forms

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Heads up... You've reached locked video content where the transcript will be shown as obfuscated text.

In previous episodes, we used a FloatingActionButton to add an onPressed interaction. Flutter provides us with some widgets that let’s us build interactivity into any widget. We would be using a GestureDetector widget to do this. This widget detects different types of gestures from a user like a tap, drag, long press and many others.

...
final article = snapshot.data![index]; // Dont ignore this!!!
return GestureDetector(
  onTap: () {
    Navigator.push<void>(
      context,
      MaterialPageRoute(
          builder: (context) => ArticlePage(article: article)),
    );
  },
  child: ArticleCard(article: article), // add this Update too!!!
);
...
ListView(
  children: <Widget>[
    ArticleMeta(article: article),
    ArticleContent(article: article),
    ArticleTags(),
    Container(
      margin: const EdgeInsets.symmetric(vertical: 16),
      height: 16,
      color: Colors.grey[300],
    )
  ]
),
class ArticleMeta extends StatelessWidget {
  final Article? article;

  const ArticleMeta({
    Key? key,
    required this.article,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16),
      child: Column(
        children: <Widget>[
          Text(
            '${article!.title}',
            style: Theme.of(context).textTheme.headline4!.copyWith(
                  fontSize: 30,
                  fontWeight: FontWeight.w600,
                ),
          ),
          const SizedBox(height: 16),
          ListTile(
            contentPadding: const EdgeInsets.all(0),
            leading: const CircleAvatar(
              child: Icon(Icons.person),
            ),
            title: Text(article!.author),
            subtitle: Text(article!.publishedAt),
            trailing: ElevatedButton(
              onPressed: () {},
              child: const Text(
                'Subscribe',
                style: TextStyle(color: Colors.white),
              ),
              style: ElevatedButton.styleFrom(
                primary: Theme.of(context).primaryColor,
              ),
            ),
          ),
          const SizedBox(height: 16),
        ],
      ),
    );
  }
}
class ArticleContent extends StatelessWidget {
  const ArticleContent({
    Key key,
    @required this.article,
  }) : super(key: key);

  final Article article;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.fromLTRB(16, 0, 16, 16),
      child: Column(
        children: <Widget>[
          Text(
            '\"${article.description}\"',
            style: Theme.of(context).textTheme.subtitle.copyWith(
                  fontStyle: FontStyle.italic,
                  color: Colors.grey[600],
                  fontSize: 20,
                ),
          ),
          SizedBox(height: 16),
          Text(
            article.content,
            style: TextStyle(fontSize: 18, height: 1.5),
          ),
          SizedBox(height: 16),
        ],
      ),
    );
  }
}
class ArticleTags extends StatelessWidget {
  const ArticleTags({ Key? key }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 16),
      child: Wrap(
        spacing: 8,
        children: <Widget>[
          const Chip(label: Text('Science')),
          const Chip(label: Text('Technology')),
          const Chip(label: Text('Devices')),
        ],
      ),
    );
  }
}
...
body: CustomScrollView(
  slivers: <Widget>[
    SliverAppBar(
      expandedHeight: 300,
      pinned: true,
      floating: true,
      elevation: 50,
      flexibleSpace: FlexibleSpaceBar(
        background: Image.network(
          '${article.urlToImage}',
          fit: BoxFit.cover,
        ),
      ),
    ),
    SliverList(
      delegate: SliverChildListDelegate(
        [
          ArticleMeta(article: article),
          ArticleContent(article: article),
          ...
        ]
      ),
    )
  ]
),