linear_border.0.dart 11.2 KB
Newer Older
1 2 3 4 5 6
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/material.dart';

7 8
/// Examples for [LinearBorder] and [LinearBorderEdge].

9 10 11 12 13
void main() {
  runApp(const ExampleApp());
}

class ExampleApp extends StatelessWidget {
14
  const ExampleApp({super.key});
15 16 17 18 19 20

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.light(useMaterial3: true),
      home: const Directionality(
21 22
        // TRY THIS: Switch to TextDirection.rtl to see how the borders change.
        textDirection: TextDirection.ltr,
23 24 25 26 27 28 29
        child: Home(),
      ),
    );
  }
}

class SampleCard extends StatelessWidget {
30
  const SampleCard({super.key, required this.title, required this.subtitle, required this.children});
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53

  final String title;
  final String subtitle;
  final List<Widget> children;

  @override
  Widget build(BuildContext context) {
    final ThemeData theme = Theme.of(context);
    final TextTheme textTheme = theme.textTheme;
    final ColorScheme colorScheme = theme.colorScheme;

    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Text(title, style: textTheme.titleMedium),
            Text(subtitle, style: textTheme.bodyMedium!.copyWith(color: colorScheme.secondary)),
            const SizedBox(height: 16),
            Row(
              children: List<Widget>.generate(children.length * 2 - 1, (int index) {
54
                return index.isEven ? children[index ~/ 2] : const SizedBox(width: 16);
55 56 57 58 59 60 61 62 63 64
              }),
            ),
          ],
        ),
      ),
    );
  }
}

class Home extends StatefulWidget {
65
  const Home({super.key});
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  final LinearBorder shape0 = LinearBorder.top();
  final LinearBorder shape1 = LinearBorder.top(size: 0);
  late LinearBorder shape = shape0;

  @override
  Widget build(BuildContext context) {
    final ColorScheme colorScheme = Theme.of(context).colorScheme;
    final BorderSide primarySide0 = BorderSide(width: 0, color: colorScheme.inversePrimary); // hairline
    final BorderSide primarySide2 = BorderSide(width: 2, color: colorScheme.onPrimaryContainer);
    final BorderSide primarySide3 = BorderSide(width: 3, color: colorScheme.inversePrimary);

    return Scaffold(
      body: SingleChildScrollView(
        child: Padding(
          padding: const EdgeInsets.all(16),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              // Demonstrates using LinearBorder.bottom() to define
              // an underline border for the standard button types.
              // The underline's color and width is defined by the ButtonStyle's
              // side parameter. The side can also be specified as a
              // LinearBorder parameter and if both are specified then the
              // ButtonStyle's side is used. This set up makes it possible
Lioness100's avatar
Lioness100 committed
96
              // for a button theme to specify the shape and for individual
97 98 99 100 101 102 103 104 105 106
              // buttons to specify the shape border's color and width.
              SampleCard(
                title: 'LinearBorder.bottom()',
                subtitle: 'Standard button widgets',
                children: <Widget>[
                  TextButton(
                    style: TextButton.styleFrom(
                      side: primarySide3,
                      shape: LinearBorder.bottom(),
                    ),
107
                    onPressed: () {},
108 109 110 111 112 113 114
                    child: const Text('Text'),
                  ),
                  OutlinedButton(
                    style: OutlinedButton.styleFrom(
                      side: primarySide3,
                      shape: LinearBorder.bottom(),
                    ),
115
                    onPressed: () {},
116 117 118 119 120 121 122
                    child: const Text('Outlined'),
                  ),
                  ElevatedButton(
                    style: ElevatedButton.styleFrom(
                      side: primarySide3,
                      shape: LinearBorder.bottom(),
                    ),
123
                    onPressed: () {},
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
                    child: const Text('Elevated'),
                  ),
                ],
              ),
              const SizedBox(height: 32),
              // Demonstrates creating LinearBorders with a single edge
              // by using the convenience constructors like LinearBorder.start().
              // The edges are drawn with a BorderSide with width:0, which
              // means that a "hairline" line is stroked. Wider borders are
              // drawn with filled rectangles.
              SampleCard(
                title: 'LinearBorder',
                subtitle: 'Convenience constructors',
                children: <Widget>[
                  TextButton(
                    style: TextButton.styleFrom(
                      side: primarySide0,
                      shape: LinearBorder.start(),
                    ),
143
                    onPressed: () {},
144 145 146 147 148 149 150
                    child: const Text('Start()'),
                  ),
                  TextButton(
                    style: TextButton.styleFrom(
                      side: primarySide0,
                      shape: LinearBorder.end(),
                    ),
151
                    onPressed: () {},
152 153 154 155 156 157 158
                    child: const Text('End()'),
                  ),
                  TextButton(
                    style: TextButton.styleFrom(
                      side: primarySide0,
                      shape: LinearBorder.top(),
                    ),
159
                    onPressed: () {},
160 161 162 163 164 165 166
                    child: const Text('Top()'),
                  ),
                  TextButton(
                    style: TextButton.styleFrom(
                      side: primarySide0,
                      shape: LinearBorder.bottom(),
                    ),
167
                    onPressed: () {},
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
                    child: const Text('Bottom()'),
                  ),
                ],
              ),
              const SizedBox(height: 32),
              // Demonstrates creating LinearBorders with a single edge
              // that's smaller than the button's bounding box. The size
              // parameter specifies a percentage of the available space
              // and alignment is -1 for start-alignment, 0 for centered,
              // and 1 for end-alignment.
              SampleCard(
                title: 'LinearBorder',
                subtitle: 'Size and alignment parameters',
                children: <Widget>[
                  TextButton(
                    style: TextButton.styleFrom(
                      side: primarySide2,
                      shape: LinearBorder.bottom(
                        size: 0.5,
                      ),
                    ),
189
                    onPressed: () {},
190 191 192 193 194 195 196 197 198 199
                    child: const Text('Center'),
                  ),
                  TextButton(
                    style: TextButton.styleFrom(
                      side: primarySide2,
                      shape: LinearBorder.bottom(
                        size: 0.75,
                        alignment: -1,
                      ),
                    ),
200
                    onPressed: () {},
201 202 203 204 205 206 207 208 209 210
                    child: const Text('Start'),
                  ),
                  TextButton(
                    style: TextButton.styleFrom(
                      side: primarySide2,
                      shape: LinearBorder.bottom(
                        size: 0.75,
                        alignment: 1,
                      ),
                    ),
211
                    onPressed: () {},
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
                    child: const Text('End'),
                  ),
                ],
              ),
              const SizedBox(height: 32),
              // Demonstrates creating LinearBorders with more than one edge.
              // In these cases the default constructor is used and each edge
              // is defined with one LinearBorderEdge object.
              SampleCard(
                title: 'LinearBorder',
                subtitle: 'LinearBorderEdge parameters',
                children: <Widget>[
                  TextButton(
                    style: TextButton.styleFrom(
                      side: primarySide0,
                      shape: const LinearBorder(
                        top: LinearBorderEdge(),
                        bottom: LinearBorderEdge(),
                      ),
                    ),
232
                    onPressed: () {},
233 234 235 236 237 238 239 240 241 242
                    child: const Text('Horizontal'),
                  ),
                  TextButton(
                    style: TextButton.styleFrom(
                      side: primarySide0,
                      shape: const LinearBorder(
                        start: LinearBorderEdge(),
                        end: LinearBorderEdge(),
                      ),
                    ),
243
                    onPressed: () {},
244 245 246 247 248 249 250 251 252 253
                    child: const Text('Vertical'),
                  ),
                  TextButton(
                    style: TextButton.styleFrom(
                      side: primarySide0,
                      shape: const LinearBorder(
                        start: LinearBorderEdge(),
                        bottom: LinearBorderEdge(),
                      ),
                    ),
254
                    onPressed: () {},
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
                    child: const Text('Corner'),
                  ),
                ],
              ),
              const SizedBox(height: 32),
              // Demonstrates that changing properties of LinearBorders
              // causes them to animate to their new configuration.
              SampleCard(
                title: 'Interpolation',
                subtitle: 'LinearBorder.top() => LinearBorder.top(size: 0)',
                children: <Widget>[
                  IconButton(
                    icon: const Icon(Icons.play_arrow),
                    onPressed: () {
                      setState(() {
                        shape = shape == shape0 ? shape1 : shape0;
                      });
                    },
                  ),
                  TextButton(
                    style: TextButton.styleFrom(
                      side: primarySide3,
                      shape: shape,
                    ),
279
                    onPressed: () {},
280 281 282 283
                    child: const Text('Press Play'),
                  ),
                  TextButton(
                    style: ButtonStyle(
284
                      side: MaterialStateProperty.resolveWith<BorderSide?>((Set<MaterialState> states) {
285 286
                        return states.contains(MaterialState.hovered) ? primarySide3 : null;
                      }),
287
                      shape: MaterialStateProperty.resolveWith<OutlinedBorder>((Set<MaterialState> states) {
288 289 290
                        return states.contains(MaterialState.hovered) ? shape0 : shape1;
                      }),
                    ),
291
                    onPressed: () {},
292 293 294 295 296 297 298 299 300 301 302
                    child: const Text('Hover'),
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}