Widget layout and page navigation developed by Flutter

1, Horizontal layout Row

Row control can be divided into two types: non flexible arrangement and flexible arrangement. It can be flexibly used by expanding outside
Mix the two:

import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      title: '',
      home: new Scaffold(
        appBar: new AppBar(title: new Text('hello row')),
        body: new Row(
          children: <Widget>[
            Expanded(                      //Flexible use
                child: new RaisedButton(
                  onPressed: () {},
                  color: Colors.blue,
                  child: new Text('Blue Button'),
                )),
            new RaisedButton(
              onPressed: () {},
              color: Colors.green,
              child: new Text('Green Button'),
            ),
          ],
        ),
      ),
    );
  }
}

2, Vertical layout Column

Alignment:

  • Main axis: for example, Row component, the horizontal axis is the main axis. For example, the Column component, vertical is the main axis.
  • cross axis: for example, Row component, the vertical axis is the secondary axis. For example, for the Columbu component, the horizontal axis is the secondary axis.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      title: '',
      home: new Scaffold(
        appBar: new AppBar(title: new Text('hello Column')),
        body: new Center(
          child: new Column(
            crossAxisAlignment: CrossAxisAlignment.center, //Minor axis alignment
            mainAxisAlignment: MainAxisAlignment.center, //Spindle alignment
            children: <Widget>[
              new Text('You don't see the Yellow River coming up,',
                  style: TextStyle(
                    color: Colors.black,
                    fontSize: 30.0,
                  )),
              new Text('The East flows to the sea and never returns,',
                  style: TextStyle(
                    color: Colors.redAccent,
                    fontSize: 30.0,
                  )),
            ],
          ),
        ),
      ),
    );
  }
}

3, Stack layout

alignment attribute: controls the position of the stack

       alignment: const FractionalOffset(dx,dy) dx,dy For 0~1
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var stack = new Stack(
      alignment: const FractionalOffset(0.5, 0.8),
      children: <Widget>[
        new CircleAvatar(
          backgroundImage:
              new NetworkImage('https://profile.csdnimg.cn/0/5/2/1_jyd0124'),
          radius: 100.0,
        ),
        new Container(
          decoration: BoxDecoration(
            color: Colors.cyan,
          ),
          child: new Text('blog_jyd0124'),
          padding: EdgeInsets.all(5.0),
        ),
      ],
    );
    // TODO: implement build
    return MaterialApp(
      title: '',
      home: new Scaffold(
        appBar: new AppBar(title: new Text('hello Stack')),
        body: new Center(child: stack),
      ),
    );
  }
}

Note: the CircleAvatar component is often used as a head portrait. The radius property can be used to set the radian of the picture

Advanced use of Stack layout: positioned is used to Stack multiple components

var stack = new Stack(
      //alignment: const FractionalOffset(0.5, 0.8),
      children: <Widget>[
        new CircleAvatar(
          backgroundImage:
              new NetworkImage('https://profile.csdnimg.cn/0/5/2/1_jyd0124'),
          radius: 100.0,
        ),
        new Positioned(
            bottom: 20.0,
            left: 60.0,
            child: new Container(
              decoration: BoxDecoration(
                color: Colors.cyan,
              ),
              child: new Text('blog_jyd0124'),
              padding: EdgeInsets.all(5.0),
            )),
      ],
    );

4, Card layout card

import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var card = new Card(
      child: new Column(
        children: <Widget>[
          ListTile(
            title: new Text('Chengdu City',style:TextStyle(fontWeight:FontWeight.w100)),
            subtitle: new Text('QQ: 150048****'),
            leading: new Icon(Icons.account_balance,color: Colors.blue,),
          ),
          ListTile(
            title: new Text('Xi'an City',style:TextStyle(fontWeight:FontWeight.w100)),
            subtitle: new Text('QQ: 150048****'),
            leading: new Icon(Icons.account_balance,color: Colors.blue,),
          ),
          ListTile(
            title: new Text('Lanzhou City',style:TextStyle(fontWeight:FontWeight.w100)),
            subtitle: new Text('QQ: 150048****'),
            leading: new Icon(Icons.account_balance,color: Colors.blue,),
          ),
        ],
      )
    );
    // TODO: implement build
    return MaterialApp(
      title: '',
      home: new Scaffold(
        appBar: new AppBar(title: new Text('hello Column')),
        body: new Center(child: card),
      ),
    );
  }
}

5, Navigation and return of pages

1.RaisedButton component

Two common attributes:

  • child: can be put into container, icon, text
  • onPressed: the response of an event. Generally, the Navigator component is called

2.Navigator components

  • Navigator.push() ====== jump to the next page, accept two parameters: context and function to jump.
  • Navigator.pop() ====== return to the previous page and accept a context parameter
import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(
      title: 'Navigation demonstration',
      home: new FirstScreen(),
    ));

class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text(''),
      ),
      body: Center(
        child: RaisedButton(
            child: Text('Jump'),
            onPressed: () {
              Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => new SecondScreen(),
                  ));
            }),
      ),
    );
  }
}

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      body: new Scaffold(
        appBar: new AppBar(title: new Text('Jump completion')),
        body: new Center(
            child: RaisedButton(
          child: Text('Return'),
          onPressed: () {
            Navigator.pop(context);
          },
        )),
      ),
    );
  }
}

6, Transmission and reception of navigation parameters

import 'package:flutter/material.dart';

class Product {
  String title;
  String description;
  Product(this.title, this.description);
}

void main() {
  runApp(MaterialApp(
    title: 'Data transfer and acceptance of navigation',
    home: ProductList(
        products:
            List.generate(20, (i) => Product('commodity $i', 'This is a product detail, No $i'))),
  ));
}

class ProductList extends StatelessWidget {
  final List<Product> products;
  ProductList({Key key, @required this.products}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('List of commodities'),
      ),
      body: ListView.builder(
          itemCount: products.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text(products[index].title),
              onTap: () {
                Navigator.push(
                    context,
                    MaterialPageRoute(
                        builder: (context) =>
                            ProductDetail(product: products[index])));
              },
            );
          }),
    );
  }
}

class ProductDetail extends StatelessWidget {
  final Product product;
  ProductDetail({Key key, @required this.product}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('${product.title}')),
      body: Center(
        child: Text('${product.description}'),
      ),
    );
  }
}
  • Tips: entering stless in Android Studio can automatically generate statelesswiidget, but in VSCode, you need to install the Awesome Flutter snippets plug-in first, and then enter stlss;

7, Page Jump and return data

1. Asynchronous request and wait
Using async await
2.SnackBar
A control for displaying prompt information will be hidden automatically. The snapbar is displayed by the showsnapbar() method of Scaffold;
3. Return data
Navigator.pop() with the second parameter

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    title: 'Page Jump return data',
    home: FirstPage(),
  ));
}

class FirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Get a number')),
      body: Center(
        child: RouteButton(),
      ),
    );
  }
}

class RouteButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return RaisedButton(
      onPressed: () {
        navigateToNumber(context);
      },
      child: Text('Get'),
    );
  }

  navigateToNumber(BuildContext context) async {
    //async is to enable asynchronous methods
    final result = await Navigator.push(
        //wait for
        context,
        MaterialPageRoute(builder: (context) => Number()));
    Scaffold.of(context).showSnackBar(SnackBar(content: Text('$result')));
  }
}

class Number extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('I'm the number you're looking for')),
      body: Center(
        child: Column(
          children: <Widget>[
            RaisedButton(
              child: Text('Two digit number'),
              onPressed: () {
                Navigator.pop(context, 'Two digit number:98');
              },
            ),
            RaisedButton(
              child: Text('Three digit number'),
              onPressed: () {
                Navigator.pop(context, 'Three digit number:124');
              },
            ),
          ],
        ),
      ),
    );
  }
}

8, Processing of static resources and project pictures

Declare the resource file in the pubspec.yaml file

Test:

import 'package:flutter/material.dart';

void main()=>runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Image.asset('images/csdn.jpg'),
    );
  }
}

9, Client packaging (Android)

1. Configure the app's image directory / android/app/src/main/res/

2. Configure the app name, icon and system permission directory / android/app/src/main/AndroidManifest.xml

3. Generate keystore
<1> The flitter doctor - V command finds the location of keytool.exe

<2> CD enters this directory, and then execute the following command, there will be a jks file under the D disk

keytool -genkey -v -keystore D:\key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key


<3> Go to the android folder in the project directory, create a file named key.properties, and open and paste the following code

storePassword=<password from previous step>    //Enter the keystore password you entered when you created the KEY in the previous step
keyPassword=<password from previous step>    //Enter the KEY password you entered when you created the KEY in the previous step
keyAlias=key
storeFile=<E:/key.jks>    //Storage path of key.jks

4. configure key registration

<1> Enter the / android/app/build.gradle file in the project directory, and add the following code before the line of android {

def keystorePropertiesFile = rootProject.file("key.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))

<2> Replace the following code
Code to replace with:

signingConfigs {
    release {
        keyAlias keystoreProperties['keyAlias']
        keyPassword keystoreProperties['keyPassword']
        storeFile file(keystoreProperties['storeFile'])
        storePassword keystoreProperties['storePassword']
    }
}
buildTypes {
    release {
        signingConfig signingConfigs.release
    }
}

5. generate apk

Enter flitter build APK in the terminal, and the package is successful. You can find it in build\app\outputs\apk\release \
Then input the fluent install in the terminal and install it directly to the

13 original articles published, 7 praised, 2864 visited
Private letter follow

Tags: Android Attribute xml Gradle

Posted on Sun, 16 Feb 2020 07:05:29 -0500 by friedemann_bach