Flutter Web 網(wǎng)站之主頁框架搭建

往期

上期回顧

上期主要完成環(huán)境的搭建和部署,最終在jetpack.net.cn地址上呈現(xiàn)心例,這期我們就開始搭建主頁,構(gòu)建一個(gè)可以兼容三端(Android、Ios楚午、Web)的主頁。

開始

在lib文件夾下創(chuàng)建home.dart文件尿招,如圖



打開文件矾柜,輸入st出來的提示選擇第一個(gè),如圖


這樣就自動(dòng)生成一個(gè)完整的模版代碼泊业,一個(gè)小小的技巧把沼,請(qǐng)笑納。最后命名PageHome吁伺,這里簡單說下命名規(guī)則饮睬,只是建議,頁面以Page開頭篮奄,非頁面以Widget開頭捆愁,這樣在其他地方引用的時(shí)候容易尋找,提高查找效率窟却。接下來昼丑,我們就用一個(gè)兼容三端的組件來構(gòu)建主頁,不賣關(guān)子夸赫,我們使用Material主題菩帝,因?yàn)槲沂茿ndroid開發(fā),更喜歡這個(gè)主題,我們?cè)谛略鼋M件的時(shí)候總感覺很麻煩呼奢,其實(shí)也有個(gè)小技巧宜雀,如圖


選第一個(gè)就可以生成一個(gè)包裹組件,繼續(xù)看圖


然后將widget改為Material握础。然后添加Padding辐董,Scaffold組件如圖



Padding的用意很簡單,加一個(gè)左右邊距禀综,而在web简烘,和手機(jī)上的邊距是不一樣的,不能固定死定枷,我畫個(gè)圖展示展示下孤澎,如圖



所以使用ResponsiveWidget判斷是否是小屏幕,如果屏幕變小則使用小邊距來適配依鸥,這里注意是小屏幕亥至,不是針對(duì)的Android或者蘋果手機(jī),要注意不能混淆理解贱迟,瀏覽器也可以縮小到手機(jī)屏幕大小對(duì)吧姐扮,要理解ResponsiveWidget請(qǐng)看前期博客:一個(gè)Flutter widget自動(dòng)適配不同UI到Web、Android
還有一個(gè)ScreenUtil衣吠,這個(gè)你可以理解為相當(dāng)于Android中的dp單位茶敏,他負(fù)責(zé)的就是等比適配,不會(huì)讓大小分辨率的屏幕看起來差距很大缚俏。這個(gè)工具有個(gè)初始化的過程

    ScreenUtil.instance = ScreenUtil.getInstance()..init(context);

而且初始化必須在MaterialApp包裹中惊搏,為什么呢?因?yàn)槲覀兪褂昧薓ediaQuery動(dòng)態(tài)獲取屏幕的寬高忧换,詳細(xì)請(qǐng)看官方文檔https://api.flutter.dev/flutter/widgets/MediaQuery-class.html里面講的很清楚:
WidgetsApp and MaterialApp, which introduce a MediaQuery and keep it up to date with the current screen metrics as they change.
目前WidgetsApp和MaterialApp實(shí)現(xiàn)了MediaQuery的邏輯恬惯,所以你不在MaterialApp中初始化是會(huì)報(bào)錯(cuò)地,知道了吧亚茬。接下來看下實(shí)際運(yùn)行效果酪耳,我們將內(nèi)容設(shè)置成紅色來看,如圖


屏幕縮小后如圖


這就是我們要的效果刹缝,其實(shí)已經(jīng)有了兩個(gè)框架封裝的很完整碗暗,但前期我們?yōu)槭裁礇]有選擇引用它們呢,而且他們實(shí)現(xiàn)的似乎更合理梢夯,請(qǐng)看他們的代碼風(fēng)格如圖


一個(gè)ScreenTypeLayout這個(gè)組件實(shí)現(xiàn)了四個(gè)屏幕的適配言疗,框架引用:

  responsive_builder: ^0.1.5

我為什么沒有選擇直接使用呢?其實(shí)我們?cè)诿靼灼渲性砗蟠_實(shí)可以直接引用颂砸,但我還是建議自己寫一遍噪奄,通過自己的實(shí)現(xiàn)死姚,更清楚其中的道理不是嗎。前期的學(xué)習(xí)過程中勤篮,我們盡量的不去引用知允,選擇自己實(shí)現(xiàn),也是加快提高自己的一個(gè)辦法叙谨。多多學(xué)習(xí),多多練習(xí)保屯。接下來我們實(shí)現(xiàn)Scaffold部分手负,Scaffold這個(gè)組件太好用了,先看下它原本的樣子


姑尺,它就像一個(gè)大的容器竟终,幫住我們組織好了各個(gè)組件的位置,是對(duì)一個(gè)基礎(chǔ)UI的高度抽象切蟋。
簡單分析下它的參數(shù)源碼


其實(shí)這里最主要的三個(gè)常用的部分appBar统捶、body、floatingActionButton柄粹,正好是我們構(gòu)建一個(gè)UI的常用構(gòu)造喘鸟,所以這個(gè)組件基本是我們使用頻率很高的一個(gè)組件,請(qǐng)認(rèn)真學(xué)習(xí)它驻右,更詳細(xì)的學(xué)習(xí)什黑,請(qǐng)看https://api.flutter.dev/flutter/material/Scaffold-class.html,這里面有幾個(gè)例子堪夭,認(rèn)真學(xué)習(xí)哦愕把,我們現(xiàn)在通過它,來構(gòu)建我們的主頁代碼森爽,請(qǐng)看效果圖:


我們先構(gòu)建了AppBar的內(nèi)容恨豁,怎么實(shí)現(xiàn)的呢,請(qǐng)看代碼

 @override
  Widget build(BuildContext context) {
    ScreenUtil.instance = ScreenUtil.getInstance()..init(context);
    return Material(
        child: Padding(
      padding: EdgeInsets.symmetric(
          horizontal: !ResponsiveWidget.isSmallScreen(context)
              ? (ScreenUtil.getInstance().setWidth(108))
              : (ScreenUtil.getInstance().setWidth(6))),
      child: Scaffold(
        appBar: AppBar(
          title: _buildTitle(),  /// 左邊標(biāo)題
          backgroundColor: Color(0xFFf1f3f4),
          actions: !ResponsiveWidget.isSmallScreen(context)
              ? _buildActions(context)
              : null,  /// 右邊的menu菜單爬迟,這里在小屏幕不顯示橘蜜。
        ),
        body: Center(child: Text('You have pressed the button $_count times.')),
      ),
    ));
  }

  Widget _buildTitle() {
    return RichText(
      text: TextSpan(
        // Note: Styles for TextSpans must be explicitly defined.
        // Child text spans will inherit styles from parent
        style: TextStyle(
          fontSize: 14.0,
          color: Colors.black,
        ),
        children: <TextSpan>[
          TextSpan(
            text: "Jetpack",
            style: TextStyles.logo,
          ),
          TextSpan(
            text: ".net.cn",
            style: TextStyles.logo.copyWith(
              color: Color(0xFF50AFC0),
            ),
          ),
        ],
      ),
    );
  }
  _buildActions(BuildContext context) {
      return <Widget>[
        MaterialButton(
          child: Text(
            'Home',
            style: TextStyles.menuItem,
          ),
          onPressed: () {
            if (ResponsiveWidget.isSmallScreen(context)) Navigator.pop(context);
          },
        ),
        MaterialButton(
          child: Text(
            'About',
            style: TextStyles.menuItem,
          ),
          onPressed: () {
            if (ResponsiveWidget.isSmallScreen(context)) Navigator.pop(context);
          },
        ),
      ];
  }

分別通過_buildTitle,_buildActions 實(shí)現(xiàn)左邊的標(biāo)題雕旨,右邊的菜單按鈕扮匠,里面有個(gè)細(xì)節(jié):


大屏幕的返回_buildActions,小屏幕直接隱藏凡涩,這里你可能有疑問棒搜,為什么不用drawer實(shí)現(xiàn)菜單?drawer適合小屏幕實(shí)現(xiàn)活箕,而大屏慕我們就要充分利用空間力麸,盡可能的操作簡單,一目了然。下面我們來實(shí)現(xiàn)克蚂,小屏幕的drawer闺鲸,請(qǐng)看代碼

///省略部分代碼
Scaffold(
        ///省略部分代碼
        drawer: _buildDrawer(context),
      ),

  _buildDrawer(BuildContext context) {
    return ResponsiveWidget.isSmallScreen(context)
        ? Drawer(
            child: ListView(
              padding: const EdgeInsets.all(20),
              children: _buildActions(context),
            ),
          )
        : null;
  }

給Scaffold添加一個(gè)drawer組件,這里用ListView把剛才的_buildActions組件再放進(jìn)來埃叭,原來是以橫向展示摸恍,這次因?yàn)長istView默認(rèn)是縱向,所以就是上下的展示方式赤屋,運(yùn)行項(xiàng)目后立镶,如圖:


未展開的樣子,標(biāo)題右邊的菜單消失



展開的樣子类早,這就是我們要實(shí)現(xiàn)的小屏幕的樣子媚媒。也符合手機(jī)的使用習(xí)慣。



有沒有發(fā)現(xiàn)這個(gè)東東顯示看不清楚涩僻,接下來我們改造它缭召,可我沒做過,我怎么查呢逆日?我這里分享我的經(jīng)驗(yàn)嵌巷,首先你要明白這里的關(guān)鍵字是什么,當(dāng)我鼠標(biāo)停留在上面的時(shí)候提示如圖

是一個(gè)navigation menu室抽,所以我會(huì)在google里搜索晴竞,flutter scaffold drawer navigation menu,這么幾個(gè)關(guān)鍵字狠半,然后搜到的如圖

噩死,第一個(gè)是官方文檔如何添加,第二個(gè)是custom drawer神年,自定義的已维,有可能講到了如何修改,所以我就點(diǎn)進(jìn)去尋找



看到?jīng)]已日,還是很好找的哈垛耳,然后copy過來代碼,發(fā)現(xiàn)它用的圖不對(duì)飘千,我們修改下堂鲜,如圖,這樣是不是看著舒服了护奈。


接下來就是給Scaffold的body填充內(nèi)容了缔莲,先看實(shí)現(xiàn)的效果
Home頁面黃色



About頁藍(lán)色



點(diǎn)擊切換,具體實(shí)現(xiàn)請(qǐng)看下面代碼
       int _selectedDrawerIndex = 0;
       ///定義一個(gè)坐標(biāo)值
      /// 添加動(dòng)態(tài)的body _getDrawerItemWidget
      child: Scaffold(
        body: _getDrawerItemWidget(_selectedDrawerIndex),
      ),
      /// 省略部分代碼
      /// 根據(jù)一個(gè)index值霉旗,來確定加載哪個(gè)頁面
  _getDrawerItemWidget(int selectedDrawerIndex) {
    switch(selectedDrawerIndex){
      case 0:
        return WidgetMenuHome();
        break;
      case 1:
        return WidgetMenuAbout();
        break;
    }
  }
/// 在_buildActions函數(shù)中的組件onPressed的時(shí)候調(diào)用痴奏,這樣就可以更新UI
  setState(() {
            _selectedDrawerIndex = 0;
          });

好了這期我們就先這樣蛀骇,學(xué)習(xí)到此結(jié)束,下期繼續(xù)读拆。

總結(jié)

這次主要是對(duì)Scaffold的使用擅憔,以及如何構(gòu)建不同平臺(tái)的UI,確切說是不同寬度屏幕的構(gòu)建檐晕,實(shí)現(xiàn)了大屏幕的Menu菜單暑诸,和小屏幕的Drawer菜單顯示,而且沒有考慮分包辟灰,下期將進(jìn)行分包設(shè)計(jì)屠列,并往頁面里面填充內(nèi)容,來構(gòu)建我們的需求UI 實(shí)現(xiàn)一個(gè)Flutter Jetpack伞矩,并把之前做的Android Jetpack也挪過來。

項(xiàng)目開源鏈接

Android Jetpack WebSite
Flutter Jetpack WebSite
Flutter Jetpack Github Source Code
Android Jetpack Github Source Code

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末夏志,一起剝皮案震驚了整個(gè)濱河市乃坤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌沟蔑,老刑警劉巖湿诊,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異瘦材,居然都是意外死亡厅须,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門食棕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來朗和,“玉大人,你說我怎么就攤上這事簿晓】衾” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵憔儿,是天一觀的道長忆植。 經(jīng)常有香客問我,道長谒臼,這世上最難降的妖魔是什么朝刊? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮蜈缤,結(jié)果婚禮上拾氓,老公的妹妹穿的比我還像新娘。我一直安慰自己底哥,他們只是感情好痪枫,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布织堂。 她就那樣靜靜地躺著,像睡著了一般奶陈。 火紅的嫁衣襯著肌膚如雪易阳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天吃粒,我揣著相機(jī)與錄音潦俺,去河邊找鬼。 笑死徐勃,一個(gè)胖子當(dāng)著我的面吹牛事示,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播僻肖,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼肖爵,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了臀脏?” 一聲冷哼從身側(cè)響起劝堪,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎揉稚,沒想到半個(gè)月后秒啦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡搀玖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年余境,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片灌诅。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡芳来,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出猜拾,到底是詐尸還是另有隱情绣张,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布关带,位于F島的核電站侥涵,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏宋雏。R本人自食惡果不足惜芜飘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望磨总。 院中可真熱鬧嗦明,春花似錦、人聲如沸蚪燕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至诗良,卻和暖如春汹桦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鉴裹。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國打工舞骆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人径荔。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓督禽,卻偏偏與公主長得像,于是被迫代替她去往敵國和親总处。 傳聞我的和親對(duì)象是個(gè)殘疾皇子狈惫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容