Flutter列表、抽屜、Tab、底部按鈕 快速實例

觀念

  1. 物件都是Widget
  2. 樹狀結構
  3. 常用元件已定好實現參數

==========================資料(post.dart)==========================

class Post{
  const Post({//類似C++的Constructor
    this.title,
    this.author,
    this.imageUrl,
  });

  final String title;
  final String author;
  final String imageUrl;
}

//初始化列表給值
final List<Post> posts = [
  Post(
    title: 'Title1',
    author: 'Author1',
    imageUrl: 'https://pics1.baidu.com/feed/c8ea15ce36d3d539258179c355f7fc56342ab0ec.jpeg?token=b1269188a783ffac3a8fa9b5d2b423f8&s=0330E02254AB0AAC261F1CC90000C0B0'
  ),
  Post(
      title: 'Title2',
      author: 'Author2',
      imageUrl: 'https://pics2.baidu.com/feed/6609c93d70cf3bc79b66c0cbbe70afa7cd112a2c.jpeg?token=2770e8c64a553b63aac48448202bfc1a&s=E1F51BC68B042F70104CD8A903005006'
  ),
  Post(
      title: 'Title3',
      author: 'Author3',
      imageUrl: 'https://pics1.baidu.com/feed/1f178a82b9014a909ccf587ff0c72f14b11beeb1.jpeg?token=e7fd680ccbf6aa973c03573b0b8c3012&s=ED85BC540C009C591CA838950300D08C'
  ),
];

======================列表(listview_demo.dart)======================

import 'package:flutter/material.dart';
import '../model/post.dart';
class MyListView extends StatelessWidget{//StatelessWidge不可改變, StatefullWidget為可改變, 此處僅顯示列表並無改變採用StatelessWidget
  Widget _listItemBuilder(BuildContext context, int index){
    return Container(
      color: Colors.white,
      margin: EdgeInsets.all(8.0),//項目margin
      child: Column(//垂直項目Column如android的linearlayout
          children: <Widget>[
            Image.network(posts[index].imageUrl),//直接使用url便能載入, 可設填滿的類型Image.network(posts[index].imageUrl, fit: BoxFit.fill,width: double.infinity,)
            SizedBox(height: 16.0,),//設空白高度(間距)
             Row(//水平項目
                mainAxisAlignment: MainAxisAlignment.start,//內容置左
                children: <Widget>[
                  Icon(Icons.check_circle, size: 30.0, color: Colors.grey[300]),
                  Image.network(posts[index].imageUrl, width: 50,),
                  new Expanded(child: Text(//填滿該文字
                    posts[index].title,
                    style: Theme.of(context).textTheme.title,
                    textAlign: TextAlign.right,
                  ),)

                ]
            ),
            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,
    );
  }
}

======================抽屜(drawer_demo.dart)======================

class Home extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Scaffold(
        drawer: MyDrawer(),
      ),
    );
  }
}
import 'package:flutter/material.dart';

class MyDrawer extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Drawer(
      child: ListView(
        padding: EdgeInsets.zero,//該項目無間距
        children: <Widget>[
          UserAccountsDrawerHeader(//大頭照及名稱信箱
            accountName: Text('Adam', style: TextStyle(fontWeight: FontWeight.bold),),
            accountEmail: Text('xxx@gmail.com', ),
            currentAccountPicture: CircleAvatar(//圓形圖
              backgroundImage: NetworkImage('https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1580055708032&di=1ce2fa1deb54ead52a9020c4beb7cd97&imgtype=0&src=http%3A%2F%2Fb.hiphotos.baidu.com%2Fzhidao%2Fpic%2Fitem%2Fa8014c086e061d9513b305a87bf40ad163d9caac.jpg'),
            ),
            decoration: BoxDecoration(//大頭照底面
                color: Colors.yellow[400],
                image: DecorationImage(//裝飾圖片
                    image: NetworkImage('https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2232748475,1633793751&fm=26&gp=0.jpg'),
                    fit: BoxFit.cover,
                    colorFilter: ColorFilter.mode(//濾鏡withOpacity給透明度
                        Colors.yellow[400].withOpacity(0.6),
                        BlendMode.hardLight
                    )
                )
            ),
          ),
          ListTile(//圖片文字項目, MyListView中Row的簡單應用可採用這個
            title: Text('Message', textAlign: TextAlign.right,),
            trailing: Icon(Icons.message, color: Colors.black12, size: 22.0,),//圖片在頭用leading, 在尾用trailing
            onTap: () => Navigator.pop(context),
          ),
          ListTile(
            title: Text('Favorite', textAlign: TextAlign.right,),
            trailing: Icon(Icons.favorite, color: Colors.black12, size: 22.0,),
            onTap: () => Navigator.pop(context),
          ),
          ListTile(
            title: Text('Setting', textAlign: TextAlign.right,),
            trailing: Icon(Icons.settings, color: Colors.black12, size: 22.0,),
            onTap: () => Navigator.pop(context),
          )
        ],
      ),
    );
  }
}

======================Tab(main.dart)======================

import 'package:flutter/material.dart';
import 'demo/basic_demo.dart';
import 'demo/bottom_navigationbar_demo.dart';
import 'demo/drawer_demo.dart';
import 'demo/listview_demo.dart';
import 'demo/hello_demo.dart';
void main() => runApp(App());
class App extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    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) {
    return DefaultTabController(
      length: 3,//tab有三頁
      child: Scaffold(
        backgroundColor: Colors.grey[100],
        appBar: AppBar(//設定標題列
          leading: IconButton(//左側按鈕, 不給會預設菜單紐, 點擊會彈開drawer
              icon: Icon(Icons.star),
              tooltip: 'Navigration',
              onPressed: () => debugPrint('Navigration button is pressed!')
          ),
          title: Text('Adam'),
          centerTitle: true,
          actions: <Widget>[//右側其餘按鈕, 可多個
            IconButton(
                icon: Icon(Icons.search),
                tooltip: 'Search',
                onPressed: () => debugPrint('Search button is pressed!')
            ),
          ],
          elevation: 0.0,//tab下方陰影, 0為沒陰影
          bottom: TabBar(
            unselectedLabelColor: Colors.black38,
              indicatorColor: Colors.black54,
              indicatorSize: TabBarIndicatorSize.label,//下方線寬度, label為包住按鈕內容, tab為整個tab寬度
              indicatorWeight: 1.0,
              tabs: <Widget>[
                Tab(icon: Icon(Icons.local_florist), text: 'test123',),//按鈕下方文字
                Tab(icon: Icon(Icons.change_history)),
                Tab(icon: Icon(Icons.directions_bike)),
              ]),
        ),
        body: TabBarView(//設定tab頁面內容, 可隨意給Icon, Text或自製的頁面
            children: <Widget>[
              MyListView(),
              Icon(Icons.change_history, size: 128.0, color: Colors.black12),
              Icon(Icons.directions_bike, size: 128.0, color: Colors.black12),
            ]
        ),
        //drawer: Container
        drawer: MyDrawer(),//設置抽屜
        bottomNavigationBar: MyBottomNavigationBar(),//設置底部按鈕
      ),
    );
  }
}

================底部按鈕(bottom_navigationbar_demo.dart)================

import 'package:flutter/material.dart';

class MyBottomNavigationBar extends StatefulWidget{//點下方按鈕要切換index, 用StatefulWidget
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _BottomNavigationBarDemoState();
  }
}
class _BottomNavigationBarDemoState extends State<MyBottomNavigationBar>{
  int _currentIndex = 0;

  void _onTabHandler(int index){//點擊動作, 設置index
    setState((){
      _currentIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return BottomNavigationBar(
        currentIndex: _currentIndex,
        onTap: _onTabHandler,
        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'),
          ),
        ]
    );
  }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341