1. 程式人生 > >(五)Flutter 介面結構 tab appbar bottomNavigationBar drawer

(五)Flutter 介面結構 tab appbar bottomNavigationBar drawer

上節課程的內容 都寫在了一起 為了解耦 我們可以把他們單獨提取出來一個類

lib 下新建demo/listview_demo.dart檔案

內容如下

import 'package:flutter/material.dart';
import 'package:nihao_flutter/model/post.dart';

class ListViewDemo extends StatelessWidget{
  Widget _listItemBuilder(BuildContext context,int index){
    return Container(
      color: Colors.white,
      margin: EdgeInsets.all(8.0),
      child: Column(
        children: <Widget>[
          Image.network(posts[index].imgeUrl),
          SizedBox(height: 16.0), 
          Text(
            posts[index].title,
            style: Theme.of(context).textTheme.title,
          ),
          Text(
            posts[index].author,
            style: Theme.of(context).textTheme.subhead,
          ),
           SizedBox(height: 16.0), 
        ],
      ),
    );
  }
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return ListView.builder(
          itemCount:posts.length,
          itemBuilder: _listItemBuilder,
        );
  }

}

lib 下新建demo/hello_demo.dart檔案

雖然這個檔案沒啥用 但是一家人就得整整齊齊的

import 'package:flutter/material.dart';

class Hello extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Center(
    child: Text(
     'Hello1111',
     textDirection: TextDirection.ltr,
     style: TextStyle(
       fontSize: 40.0,
       fontWeight: FontWeight.bold,
       color: Colors.black87
     ),
      ),
  
  );
  }

}

test/widget_test.dart老報錯  說沒有MyApp  真是怕了你了 把app 改成MyApp

每次app執行上面都有一個debug 可以去掉的

      debugShowCheckedModeBanner: false,
import 'package:flutter/material.dart';
import 'package:nihao_flutter/demo/listview_demo.dart';



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



class MyApp extends StatelessWidget{ 
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Home(),
      theme: ThemeData(
        primarySwatch: Colors.yellow
      ),
    );
  }
  
}


  
class Home extends StatelessWidget{
  
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      backgroundColor: Colors.grey[100],
        appBar: AppBar(
          title: Text('app Bar'),
          // 陰影
          elevation: 0.0,
        ),
        body: ListViewDemo()
      );
  }

}

內容和上節一樣 但是更方便以後的修改和開發了

so

繼續本節課內容

AppBar:工具欄上的圖示按鈕(IconButton)

控制檯列印

()=>debugPrint('search Button is pressed.')

整體程式碼如下

import 'package:flutter/material.dart';
import 'package:nihao_flutter/demo/listview_demo.dart';



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



class MyApp extends StatelessWidget{ 
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Home(),
      theme: ThemeData(
        primarySwatch: Colors.yellow
      ),
    );
  }
  
}


  
class Home extends StatelessWidget{
  
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      backgroundColor: Colors.grey[100],
        appBar: AppBar(
          leading: IconButton(
            icon: Icon(Icons.menu),
            tooltip: 'Navigration',
            onPressed: ()=>debugPrint('Navigration Button is pressed.'),
          ),
          title: Text('app Bar'),
          actions: <Widget>[
            IconButton(
            icon: Icon(Icons.search),
            tooltip: 'Search',
            onPressed: ()=>debugPrint('search Button is pressed.'),
          ),
          ],
          // 陰影
          elevation: 0.0,
        ),
        body: null
      );
  }

}

android 叫做TabLayout Flutter 叫做TabBar :用標籤形式展示內容

具體程式碼如下

import 'package:flutter/material.dart';
import 'package:nihao_flutter/demo/listview_demo.dart';



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



class MyApp extends StatelessWidget{ 
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Home(),
      theme: ThemeData(
        primarySwatch: Colors.yellow
      ),
    );
  }
  
}


  
class Home extends StatelessWidget{
  
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return DefaultTabController(
      length: 3,
      child: Scaffold(
      backgroundColor: Colors.grey[100],
        appBar: AppBar(
          leading: IconButton(
            icon: Icon(Icons.menu),
            tooltip: 'Navigration',
            onPressed: ()=>debugPrint('Navigration Button is pressed.'),
          ),
          title: Text('app Bar'),
          actions: <Widget>[
            IconButton(
            icon: Icon(Icons.search),
            tooltip: 'Search',
            onPressed: ()=>debugPrint('search Button is pressed.'),
          ),
          ],
          // 陰影
          elevation: 0.0,
          bottom: TabBar(
            tabs: <Widget>[
              Tab(icon: Icon(Icons.local_florist)),
              Tab(icon: Icon(Icons.change_history)),
              Tab(icon: Icon(Icons.directions_bike)),
            ],
          ),
        ),
        body: TabBarView(children: <Widget>[
          Icon(Icons.local_florist,size: 128.0,color: Colors.black12),
          Icon(Icons.change_history,size: 128.0,color: Colors.black12),
          Icon(Icons.directions_bike,size: 128.0,color: Colors.black12),
        ],)
      ),
    );
  }

}

在設定下點選狀態

 bottom: TabBar(
            unselectedLabelColor: Colors.black38,
            indicatorColor: Colors.black54,
            indicatorSize: TabBarIndicatorSize.label,
            indicatorWeight:1.0 ,
            tabs: <Widget>[
              Tab(icon: Icon(Icons.local_florist)),
              Tab(icon: Icon(Icons.change_history)),
              Tab(icon: Icon(Icons.directions_bike)),
            ],

對tab增加水波紋效果

class MyApp extends StatelessWidget{ 
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Home(),
      theme: ThemeData(
        primarySwatch: Colors.yellow,
        highlightColor: Color.fromRGBO(255, 255, 255, 0.5),
        splashColor: Colors.white70
      ),
    );
  }
  
}

現在具體原始碼如下

import 'package:flutter/material.dart';
import 'package:nihao_flutter/demo/listview_demo.dart';



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



class MyApp extends StatelessWidget{ 
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Home(),
      theme: ThemeData(
        primarySwatch: Colors.yellow,
        highlightColor: Color.fromRGBO(255, 255, 255, 0.5),
        splashColor: Colors.white70
      ),
    );
  }
  
}


  
class Home extends StatelessWidget{
  
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return DefaultTabController(
      length: 3,
      child: Scaffold(
      backgroundColor: Colors.grey[100],
        appBar: AppBar(
          leading: IconButton(
            icon: Icon(Icons.menu),
            tooltip: 'Navigration',
            onPressed: ()=>debugPrint('Navigration Button is pressed.'),
          ),
          title: Text('app Bar'),
          actions: <Widget>[
            IconButton(
            icon: Icon(Icons.search),
            tooltip: 'Search',
            onPressed: ()=>debugPrint('search Button is pressed.'),
          ),
          ],
          // 陰影
          elevation: 0.0,
          bottom: TabBar(
            unselectedLabelColor: Colors.black38,
            indicatorColor: Colors.black54,
            indicatorSize: TabBarIndicatorSize.label,
            indicatorWeight:1.0 ,
            tabs: <Widget>[
              Tab(icon: Icon(Icons.local_florist)),
              Tab(icon: Icon(Icons.change_history)),
              Tab(icon: Icon(Icons.directions_bike)),
            ],
          ),
        ),
        body: TabBarView(children: <Widget>[
          Icon(Icons.local_florist,size: 128.0,color: Colors.black12),
          Icon(Icons.change_history,size: 128.0,color: Colors.black12),
          Icon(Icons.directions_bike,size: 128.0,color: Colors.black12),
        ],)
      ),
    );
  }

}

Flutter Drawer 抽屜(側邊欄)

從左到右邊就是

drwer:widget

從右邊到左邊就是

endDrawer:widget

先寫一個簡單的drawer 不寫動作 直接從左往右即可滑動出現

import 'package:flutter/material.dart';
import 'package:nihao_flutter/demo/listview_demo.dart';



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



class MyApp extends StatelessWidget{ 
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Home(),
      theme: ThemeData(
        primarySwatch: Colors.yellow,
        highlightColor: Color.fromRGBO(255, 255, 255, 0.5),
        splashColor: Colors.white70
      ),
    );
  }
  
}


  
class Home extends StatelessWidget{
  
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return DefaultTabController(
      length: 3,
      child: Scaffold(
      backgroundColor: Colors.grey[100],
        appBar: AppBar(
          leading: IconButton(
            icon: Icon(Icons.menu),
            tooltip: 'Navigration',
            onPressed: ()=>debugPrint('Navigration Button is pressed.'),
          ),
          title: Text('app Bar'),
          actions: <Widget>[
            IconButton(
            icon: Icon(Icons.search),
            tooltip: 'Search',
            onPressed: ()=>debugPrint('search Button is pressed.'),
          ),
          ],
          // 陰影
          elevation: 0.0,
          bottom: TabBar(
            unselectedLabelColor: Colors.black38,
            indicatorColor: Colors.black54,
            indicatorSize: TabBarIndicatorSize.label,
            indicatorWeight:1.0 ,
            tabs: <Widget>[
              Tab(icon: Icon(Icons.local_florist)),
              Tab(icon: Icon(Icons.change_history)),
              Tab(icon: Icon(Icons.directions_bike)),
            ],
          ),
        ),
        body: TabBarView(children: <Widget>[
          Icon(Icons.local_florist,size: 128.0,color: Colors.black12),
          Icon(Icons.change_history,size: 128.0,color: Colors.black12),
          Icon(Icons.directions_bike,size: 128.0,color: Colors.black12),
        ],),
      drawer: Container(
        color: Colors.white,
        padding: EdgeInsets.all(8.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('This is Drawer')
          ],
        ),
      ),
      ),
    );
  }

}

稍微規範一點

import 'package:flutter/material.dart';
import 'package:nihao_flutter/demo/listview_demo.dart';



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



class MyApp extends StatelessWidget{ 
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Home(),
      theme: ThemeData(
        primarySwatch: Colors.yellow,
        highlightColor: Color.fromRGBO(255, 255, 255, 0.5),
        splashColor: Colors.white70
      ),
    );
  }
  
}


  
class Home extends StatelessWidget{
  
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return DefaultTabController(
      length: 3,
      child: Scaffold(
      backgroundColor: Colors.grey[100],
        appBar: AppBar(
          leading: IconButton(
            icon: Icon(Icons.menu),
            tooltip: 'Navigration',
            onPressed: ()=>debugPrint('Navigration Button is pressed.'),
          ),
          title: Text('app Bar'),
          actions: <Widget>[
            IconButton(
            icon: Icon(Icons.search),
            tooltip: 'Search',
            onPressed: ()=>debugPrint('search Button is pressed.'),
          ),
          ],
          // 陰影
          elevation: 0.0,
          bottom: TabBar(
            unselectedLabelColor: Colors.black38,
            indicatorColor: Colors.black54,
            indicatorSize: TabBarIndicatorSize.label,
            indicatorWeight:1.0 ,
            tabs: <Widget>[
              Tab(icon: Icon(Icons.local_florist)),
              Tab(icon: Icon(Icons.change_history)),
              Tab(icon: Icon(Icons.directions_bike)),
            ],
          ),
        ),
        body: TabBarView(children: <Widget>[
          Icon(Icons.local_florist,size: 128.0,color: Colors.black12),
          Icon(Icons.change_history,size: 128.0,color: Colors.black12),
          Icon(Icons.directions_bike,size: 128.0,color: Colors.black12),
        ],),
      drawer: Drawer(
        child: ListView(
          padding: EdgeInsets.zero,
          children: <Widget>[
            DrawerHeader(
              child: Text('header'.toUpperCase()),
              decoration: BoxDecoration(
                color: Colors.grey[100]
              )
            ),
ListTile(
  title: Text(
    'Messages',
    textAlign:TextAlign.right  
  ),
  trailing: Icon(Icons.message,color:Colors.black12,size:22.0),
),
ListTile(
  title: Text(
    'Favorite',
    textAlign:TextAlign.right  
  ),
  trailing: Icon(Icons.favorite,color:Colors.black12,size:22.0),
),
ListTile(
  title: Text(
    'Settings',
    textAlign:TextAlign.right  
  ),
  trailing: Icon(Icons.settings,color:Colors.black12,size:22.0),
),

          ],
        ),

      )
      ),
    );
  }

}

提取出來Drawer小空間 到lib/demo/drawer_demo.dart

import 'package:flutter/material.dart';
class DrawerDemo extends StatelessWidget{
  @override
    Widget build(BuildContext context) {
      // TODO: implement build
      return Drawer(
            child: ListView(
              padding: EdgeInsets.zero,
              children: <Widget>[
               UserAccountsDrawerHeader(
                 accountName: Text(
                   'liuan',
                   style:TextStyle(fontWeight:FontWeight.bold)
                   ),
                   accountEmail: Text('[email protected]'),
                   currentAccountPicture: CircleAvatar(
                     backgroundImage: NetworkImage("https://qlogo3.store.qq.com/qzone/1377093782/1377093782/100?1517837561"),
                   ),
                   decoration: BoxDecoration(
                     color: Colors.yellow[400],
                     image: DecorationImage(
                       image: NetworkImage("https://b17.photo.store.qq.com/psb?/V12afHjz3YxmJJ/wsSH2RiAY5hw.wpvEsjHmXdBttWDcJGcbjdvPUNrPZc!/b/dBEAAAAAAAAA&bo=QAZZCEAGWQgRIBc!&rf=viewer_311"),
                       fit: BoxFit.cover,
                       colorFilter: ColorFilter.mode(Colors.yellow[400], BlendMode.hardLight)
                     )
                   ),
               ),
                ListTile(
                  title: Text('Messages', textAlign: TextAlign.right),
                  trailing:
                      Icon(Icons.message, color: Colors.black12, size: 22.0),
                ),
                ListTile(
                  title: Text('Favorite', textAlign: TextAlign.right),
                  trailing:
                      Icon(Icons.favorite, color: Colors.black12, size: 22.0),
                ),
                ListTile(
                  title: Text('Settings', textAlign: TextAlign.right),
                  trailing:
                      Icon(Icons.settings, color: Colors.black12, size: 22.0),
                ),
              ],
            ),
          );
    }
}

主頁程式碼如下

import 'package:flutter/material.dart';
import 'package:nihao_flutter/demo/drawer_demo.dart';
import 'package:nihao_flutter/demo/listview_demo.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Home(),
      theme: ThemeData(
          primarySwatch: Colors.yellow,
          highlightColor: Color.fromRGBO(255, 255, 255, 0.5),
          splashColor: Colors.white70),
    );
  }
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return DefaultTabController(
      length: 3,
      child: Scaffold(
          backgroundColor: Colors.grey[100],
          appBar: AppBar(
            leading: IconButton(
              icon: Icon(Icons.menu),
              tooltip: 'Navigration',
              onPressed: () => debugPrint('Navigration Button is pressed.'),
            ),
            title: Text('app Bar'),
            actions: <Widget>[
              IconButton(
                icon: Icon(Icons.search),
                tooltip: 'Search',
                onPressed: () => debugPrint('search Button is pressed.'),
              ),
            ],
            // 陰影
            elevation: 0.0,
            bottom: TabBar(
              unselectedLabelColor: Colors.black38,
              indicatorColor: Colors.black54,
              indicatorSize: TabBarIndicatorSize.label,
              indicatorWeight: 1.0,
              tabs: <Widget>[
                Tab(icon: Icon(Icons.local_florist)),
                Tab(icon: Icon(Icons.change_history)),
                Tab(icon: Icon(Icons.directions_bike)),
              ],
            ),
          ),
          body: TabBarView(
            children: <Widget>[
              Icon(Icons.local_florist, size: 128.0, color: Colors.black12),
              Icon(Icons.change_history, size: 128.0, color: Colors.black12),
              Icon(Icons.directions_bike, size: 128.0, color: Colors.black12),
            ],
          ),
          drawer: DrawerDemo()),
    );
  }
}

demo 下新建bottom_navigation_bar_demo.dart

import 'package:flutter/material.dart';
class BottomNavigationBarDemo extends StatefulWidget{
  @override
    State<StatefulWidget> createState() {
      // TODO: implement createState
      return _BottomNavigationBarDemoState();
                }
            
          
      }
      
      class _BottomNavigationBarDemoState extends State<BottomNavigationBarDemo>{
          int _currentIndex=0;
  void _onTapHandler(int index){
    setState((){
      _currentIndex=index;
    });
  }
        @override
          Widget build(BuildContext context) {
            // TODO: implement build
            return BottomNavigationBar(
            currentIndex:_currentIndex,
            onTap: _onTapHandler,
            type: BottomNavigationBarType.fixed,
            fixedColor: Colors.black,
            items: [
              BottomNavigationBarItem(
                icon: Icon(Icons.explore),
                title: Text('Explore')
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.history),
                title: Text('History')
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.list),
                title: Text('List')
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.person),
                title: Text('My')
              ),
            ],
          );
          }

}

main.dart

import 'package:flutter/material.dart';
import 'package:nihao_flutter/demo/bottom_navigation_bar_demo.dart';
import 'package:nihao_flutter/demo/drawer_demo.dart';
import 'package:nihao_flutter/demo/listview_demo.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Home(),
      theme: ThemeData(
          primarySwatch: Colors.yellow,
          highlightColor: Color.fromRGBO(255, 255, 255, 0.5),
          splashColor: Colors.white70),
    );
  }
}

class Home extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return DefaultTabController(
      length: 3,
      child: Scaffold(
          backgroundColor: Colors.grey[100],
          appBar: AppBar(
            leading: IconButton(
              icon: Icon(Icons.menu),
              tooltip: 'Navigration',
              onPressed: () => debugPrint('Navigration Button is pressed.'),
            ),
            title: Text('app Bar'),
            actions: <Widget>[
              IconButton(
                icon: Icon(Icons.search),
                tooltip: 'Search',
                onPressed: () => debugPrint('search Button is pressed.'),
              ),
            ],
            // 陰影
            elevation: 0.0,
            bottom: TabBar(
              unselectedLabelColor: Colors.black38,
              indicatorColor: Colors.black54,
              indicatorSize: TabBarIndicatorSize.label,
              indicatorWeight: 1.0,
              tabs: <Widget>[
                Tab(icon: Icon(Icons.local_florist)),
                Tab(icon: Icon(Icons.change_history)),
                Tab(icon: Icon(Icons.directions_bike)),
              ],
            ),
          ),
          body: TabBarView(
            children: <Widget>[
              ListViewDemo(),
              Icon(Icons.change_history, size: 128.0, color: Colors.black12),
              Icon(Icons.directions_bike, size: 128.0, color: Colors.black12),
            ],
          ),
          drawer: DrawerDemo(),
          bottomNavigationBar: BottomNavigationBarDemo(),
          
          ),
    );
  }
}

Flutter 底部導航欄

BottomNavigationBar也完成了