This is the 10th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

1. Status management

A state is a concept. In iOS, any control has some response that changes its style. A change of state is required whenever a component changes in flutter. In FLUTTER, there is incremental rendering. If a property occurs, the Widget tree will be rebuilt. That is, a new Widget instance will be created to replace the old Widget instance. This is why properties defined in widgets must be final. Page logic is separate from data logic in Flutter. It preserves data and replaces pages. Flutter contains a StatefulWidget that holds data logic. The StatefulWidget encapsulates data logic and page logic.

Create a StatelessWidget and count++ when clicked.

class StateManagerDemo extends StatelessWidget { //const StateManagerDemo({Key? key}) : super(key: key); int count = 0; @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.grey[100], appBar: AppBar( title: const Text("Layout Demo"), ), body: Center( child: Chip(label:Text("$count"),), ), floatingActionButton: FloatingActionButton( onPressed: () { count++; print("$count"); }, child: const Icon(Icons.add), ), ); }}Copy the code

After running, the count changes, but the UI does not.

This is where the StatefulWidget comes in.

class StateManagerDemo extends StatefulWidget { const StateManagerDemo({Key? key}) : super(key: key); @override _StateManagerDemoState createState() => _StateManagerDemoState(); } class _StateManagerDemoState extends State<StateManagerDemo> { int count = 0; @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.grey[100], appBar: AppBar( title: const Text("Layout Demo"), ), body: Center( child: Chip(label:Text("$count"),), ), floatingActionButton: FloatingActionButton( onPressed: () { count++; print("$count"); }, child: const Icon(Icons.add), ), ); }}Copy the code

This time, the click still does not change, but after hot reload, the middle number changes, indicating that the data is still preserved. Count++ should be placed in setState so that the page will change, because calling setState will re-build the page, and the build will still be incremental.

  onPressed: () {
          setState(() {
            count++;

          });
          print("$count");
        },
Copy the code

The _StateManagerDemoState class is private and cannot be accessed by the state manager. The _StateManagerDemoState class cannot accept data directly. StateManagerDemo has all exposed interfaces. _StateManagerDemoState Can access data in StateManagerDemo and retain it. In other words, the management of data is in _StateManagerDemoState.

2. Project construction

2.1 Bottom Navigation Bar

Create a new project. Change MyHomePage to the following structure.

class MyHomePage extends StatelessWidget { const MyHomePage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Container( ); }}Copy the code

Change the Widget returned by MyHomePage to Scaffold and add bottomNavigationBar.

return Scaffold( bottomNavigationBar: BottomNavigationBar( type: BottomNavigationBarType.fixed, fixedColor: Colors.green, items: const [ BottomNavigationBarItem(icon: Icon(Icons.chat), label: BottomNavigationBarItem(icon: icon (Icons. Bookmark), label: "address book "), BottomNavigationBarItem(icon: Icon(Icons. History), label: "find "), BottomNavigationBarItem(Icon: Icon(Icons. Person), label:" I "),],);Copy the code

The next step is to switch the selected item, save the data, change the MyHomePage into a StatefulWidget, and change _currentIndex with the onTap call setState in BottomNavigationBar.

class MyHomePage extends StatefulWidget { const MyHomePage({Key? key}) : super(key: key); @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { int _currentIndex = 0; @override Widget build(BuildContext context) { return Scaffold( bottomNavigationBar: BottomNavigationBar( type: BottomNavigationBarType.fixed, currentIndex: _currentIndex, fixedColor: Colors.green, items: Const [BottomNavigationBarItem(icon: icon (Icons. Chat), label: "微信"), BottomNavigationBarItem(icon: Icon(Icons. Bookmark), label: "address book "), BottomNavigationBarItem(Icon: Icon(Icons. History), label: BottomNavigationBarItem(icon: icon (Icons. Person), label: "I "),], onTap: (index){ setState(() { _currentIndex = index; }); },),); }}Copy the code

Next, create the four interfaces, all of which are set to StatefulWidget. However, the entire page is usually developed as a StatelessWidget, and only the page that needs to be changed is set as a StatefulWidget. The Scaffold is then provided with a List of four pages and the body in that Scaffold uses the page at currentIndex.

class _MyHomePageState extends State<MyHomePage> { int _currentIndex = 0; List<Widget> _pages = [ChatPage(),FriendsPage(),DiscoverPage(),MinePage()]; @override Widget build(BuildContext context) { return Scaffold( body: _pages[_currentIndex], bottomNavigationBar: BottomNavigationBar( type: BottomNavigationBarType.fixed, currentIndex: _currentIndex, fixedColor: Colors.green, items: Const [BottomNavigationBarItem(icon: icon (Icons. Chat), label: "微信"), BottomNavigationBarItem(icon: Icon(Icons. Bookmark), label: "address book "), BottomNavigationBarItem(Icon: Icon(Icons. History), label: BottomNavigationBarItem(icon: icon (Icons. Person), label: "I "),], onTap: (index){ setState(() { _currentIndex = index; }); },),); }}Copy the code

Click at this time, you can switch pages.

You see that when you click on the switch above, there’s an animation, we don’t need this animation, so we can remove it from the MaterialApp. ThemeData in the MaterialApp modiates the highlightColor and splashColor so that the animation disappears. You can modify primarySwatch to change the theme color.

return MaterialApp( title: 'Flutter Demo', theme: ThemeData( highlightColor: Const color.fromrgbo (1, 0, 0, 0.0), splashColor: const color.fromrgbo (1, 0, 0, 0.0), primarySwatch: Colors.green, ), home: const MyHomePage(), ); }Copy the code

There’s also an animation where the font gets bigger, so you can change selectedFontSize at BottomNavigationBar.

 selectedFontSize: 12,
Copy the code

2.2 Name and icon of the program

Go to androidmanifest.xml for Android — app — SRC — main. Here you can change the name and icon of the program.

Android :label=" hello hello"Copy the code

To use ICONS, import images first. Click on the RES at the top and see hdPI (iOS 1x), MDPI (iOS 1.5x), xhdPI (iOS 2x), xxhdPI (iOS 3x), xxxhdpi (iOS 4x). Copy the image to the corresponding folder, name it not hump and include Chinese.

android:icon="@mipmap/app_icon">
Copy the code

The boot image is configured in Drawable and drawable- V21.

  <item>
        <bitmap
            android:gravity="center"
            android:src="@mipmap/launch_image" />
    </item>
Copy the code

2.3 Assets

The Flutter APP installation package contains both code and assets. Assets are packaged into the installation package and can be accessed at run time. Common types of assets include static data (such as JSON files), configuration files, ICONS, and images.

I’m going to add an Images folder here, and I’m going to put Images in the Images folder.

Flutter uses the pubspec.yaml file to manage the resources required by the application. Package management is also in the pubspec.yaml file. To add references to a file, the format is very important, one more space or one less space will not do.

You can then go to BottomNavigationBar to change the icon to your own image, where you need to set the activeIcon to distinguish between checked and unchecked states.

BottomNavigationBarItem(icon: Image(image: AssetImage("images/tabbar_chat.png"),height: 20,width: 20,),activeIcon: Image(image: AssetImage("images/tabbar_chat_hl.png"),height: 20,width: 20,), label: BottomNavigationBarItem(icon: Image(Image: AssetImage("images/tabbar_friends.png"),height: 20,width: 20,),activeIcon: Image(image: AssetImage("images/tabbar_friends_hl.png"),height: 20,width: 20,), label: "Address book "), BottomNavigationBarItem(icon: Image(Image: AssetImage("images/tabbar_discover.png"),height: 20,width: 20,),activeIcon: Image(image: AssetImage("images/tabbar_discover_hl.png"),height: 20,width: 20,), label: BottomNavigationBarItem(icon: Image(Image: AssetImage("images/tabbar_mine.png"),height: 20,width: 20,), activeIcon: Image(Image: AssetImage("images/tabbar_mine_hl.png"),height: 20,width: 20,),label: "I "),Copy the code

3. Summary

  • State management of Flutter
    • StatelessWidget StatelessWidget
    • StatefulWidget has a StatefulWidget
      • Inherits the StatefulWidget to provide interfaces externally
        • Implement the createState method method
      • Inheriting State is used to manage State
        • Implement the build method. Access the data, the data is in state
        • Set/change data with setState