1. BoxFit is worth meaning

When displaying an Image using the Image Widget, we give it a stretch rule for the Image using the FIT parameter, for example:

Image.asset('assets/top.jpeg',fit: BoxFit.cover),
Copy the code

BixFit itself is an enumeration:

It represents how the remaining space of the outer box is utilized when one box is built into another.

enum BoxFit {
  fill,

  contain,

  cover,

  fitWidth,

  fitHeight,

  none,

  scaleDown,
}
Copy the code

1.1 BoxFit. The fill

Fills the parent container. Width and height may be stretched or compressed to fit the parent container.

1.2 BoxFit. Contain

As large as possible, but within the boundaries of the parent container. If the width and height of the child element do not match the width and height of the parent container, it is possible to leave a blank area to the left and right or above and below the child element.

1.3 BoxFit. Cover

Fill the container, it might be truncated.

1.4 BoxFit.fitWidth

The image may be truncated by filling the width.

1.5 BoxFit.fitHeight

The width may be truncated if the image is filled with height

1.6 BoxFit. None

The default display is centered in the middle of the container. If it exceeds the width and height of the parent container, the excess portion is truncated. If it does not exceed the width and height of the parent container, center it directly.

1.7 BoxFit.scaleDown

Contain boxfit. contain is the same as BoxFit. If it does not exceed the width and height of the parent container, it is directly centered, as with Boxfit.None.

2. Stateful and stateless widgets

The only difference between a stateful Widget and a stateless Widget is whether the Widget changes after it interacts with the user.

For example, the user can check the Checkbox.

The State of a widget is stored in a State object, which is separate from the display of the widget. The status of a Widget is a set of values that can be changed, such as whether a check box is selected. When the widget State changes, the State object calls setState(), telling the framework to redraw the widget.

How do I create a StatefulWidget

You need to create two classes: a StatefulWidget subclass and a State subclass.

Example: Click the favorites button to update the number of favorites

///Create a subclass of StatefulWidget
///
///The FavoriteWidget class manages its own state, so it creates the state object by overriding createState(). The framework calls createState() when the widget is built.
///In this example, createState() is created_FavoriteWidgetState instance, which is implemented in the next step.
class FavoriteWidget extends StatefulWidget {
  @override
  _FavoriteWidgetState createState() => _FavoriteWidgetState();
}
Copy the code
class _FavoriteWidgetState extends State<FavoriteWidget> {
  // The state object stores information in the _isFavorited and _favoriteCount variables.
  bool _isFavorited = true;// Whether to collect
  int _favoriteCount = 41;// The number of collections

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Container(
          padding: EdgeInsets.all(0),
          child: IconButton(
            padding: EdgeInsets.all(0),
            alignment: Alignment.centerRight,
            icon: (_isFavorited ? Icon(Icons.star) : Icon(Icons.star_border)),
            color: Colors.red[500],
            onPressed: _toggleFavorite,
          ),
        ),
        SizedBox(
          width: 18,
          child: Container(
            child: Text('$_favoriteCount'(), [[(), [(). }void _toggleFavorite() {
  setState(() {
    if (_isFavorited) {
      _favoriteCount -= 1;
      _isFavorited = false;
    } else {
      _favoriteCount += 1;
      _isFavorited = true; }}); }}Copy the code

Operation effect:

3. What does a page in a Flutter refer to?

In Flutter we use screen to represent a page, which is essentially a Widget.

So what is routing?

In Android development, an Activity is “routing”; in iOS development, a ViewController is “routing.” In Flutter, “routing” is also a widget.

4. How to transfer values between Flutter pages?

There are two main ways to navigate from one page to another in Flutter:

  1. Navigator.push()
onPressed: () {
  Navigator.push(
    context,
    MaterialPageRoute(builder: (context) => SecondRoute()),
  );
}
Copy the code
  1. Named route navigator.pushnamed ()
onPressed: () {
  Navigator.pushNamed(context, '/second');
}
Copy the code

Use different navigation modes, the way of value transfer is also different, the following are respectively:

4.1 There are two ways to pass values using navigator.push ()

First: pass the value through the constructor

Start by defining the constructor on the target page

class SecondScreen extends StatelessWidget {
  // The SecondScreen page requires a title parameter
  SecondScreen({Key key, @required this.title}) : super(key: key); . }Copy the code

By value:

onPressed: () {
  Navigator.push(
    context,
    MaterialPageRoute(
      builder: (context) => SecondScreen(title: 'parameters',)))}Copy the code

Second: Pass parameters using RouteSettings

Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) => RouteManager(),
    settings: RouteSettings(arguments: 'parameters')))Copy the code

Receive arguments: modalroute.of (context).settings.arguments

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Receive parameters
    final String title = ModalRoute.of(context).settings.arguments;

    // Use the title to create the UI.
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: Padding(
        padding: EdgeInsets.all(16.0), child: Text(title), ), ); }}Copy the code

4.2 The value transfer method when using Navigator.pushnamed ()

Navigator.pushNamed(
  context,
  'Route Name',
  arguments:'parameters'
)
Copy the code

You can also use modalroute.of (context).settings.arguments

4.3 adapter

So here’s the problem: if a page has a constructor that must accept an argument, and I want to use command routing to jump to that page, what should I do?

Suppose the page is:

class SecondScreen extends StatelessWidget {
  // The SecondScreen page requires a title parameter
  SecondScreen({Key key, @required this.title}) : super(key: key);

  final Stringtitle; . }Copy the code

Route registration mode:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(

      // omit silent code.// Register the routing table
      routes: {
        'second': (context) => SecondScreen( title: ModalRoute.of(context).settings.arguments, ), }, ); }}Copy the code

4.4 Sending Data Back from a Page

I’ve seen how to pass values to a new route, but what if I go back to the previous page?

Navigator.pop(context, 'Returned value');
Copy the code

Receives the value returned from the previous page and displays it via a SnackBar:

void _navigateAndDisplay(BuildContext context) async {
  // Navigate and receive the results
  final result =
      await Navigator.pushNamed(context, 'second', arguments: 'parameters'); Scaffold.of(context) .. removeCurrentSnackBar() .. showSnackBar(SnackBar(content: Text("$result")));
}
Copy the code

5. Hero Animations that switch across pages

How to create a visual anchoring relationship between two pages by animating a component during page transitions. As follows:

Flutter provides us with Hero animations to achieve:

Code examples:

///First page
class HeroDemoScreen extends StatelessWidget {
  static const routeName = '/HeroDemoScreen';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Hero animations'),
      ),
      body: GestureDetector(
        child: Hero(
            tag: 'imageHero',
            child: Image.network('https://picsum.photos/250? image=9')), onTap: () => {Navigator.pushNamed(context, ImageScanScreen.routeName)}, ), ); }}Copy the code
///Second page
class ImageScanScreen extends StatelessWidget {
  static const routeName = '/ImageScanScreen';

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('View pictures'),
      ),
      body: GestureDetector(
        child: Center(
          child: Hero(
              tag: 'imageHero',
              child: Image.network('https://picsum.photos/250? image=9')), ), onTap: ()=>{ Navigator.pop(context) }, ), ); }}Copy the code

To animate the connection between two pages, wrap the Image component of each page inside the Hero component. The Hero component takes two arguments:

  1. tag

As an identity for the Hero component, it must be the same on both pages.

  1. child

The widget that the two screens directly span is, in this case, the Image.

Hero(
  tag: 'imageHero',
  child: Image.network(
    'https://picsum.photos/250? image=9',),);Copy the code