FlutterApp首頁實現(xiàn)

首頁實現(xiàn)總結

目錄

  • 根布局
  • Banner圖
  • AppBar
  • 卡片布局
image.png

根布局

根布局使用Scaffold掉瞳,這個是material包下的組件,它是一個路由頁的骨架浪漠,可以非常容易的拼裝出一個完整的頁面陕习。進入首頁先顯示加載,通過網(wǎng)絡訪問得到數(shù)據(jù)后關閉址愿,還要支持下拉刷新的功能该镣。
技術點:
MediaQuery.removePadding移除系統(tǒng)欄Padding
RefreshIndicator控制下拉刷新。ListView滾動的時候响谓,并且檢查滾動的深度為0损合,防止子View的滾動造成性能損耗。
ListView利用顯示的自列表來構造 List<Widget>娘纷。此構造函數(shù)適合于具有少量子元素的列表視圖嫁审,因為構造列表需要為可能顯示在列表視圖中的每個子元素執(zhí)行工作,而不僅僅是那些實際可見的子元素赖晶。
_handleRefresh 是Flutter中的異步函數(shù)土居,在未來某個時刻執(zhí)行。主要用來獲取網(wǎng)絡數(shù)據(jù)嬉探。

@override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Color(0xfff2f2f2),
        body: LoadingContainer(// 加載頁面
            isLoading: _loading,// 控制加載頁面
            child: Stack(// ListView與AppBar 類似Stack結構擺放
              children: <Widget>[
                MediaQuery.removePadding(// 去掉系統(tǒng)欄的Padding
                  // 去掉頂部屏幕適配
                  removeTop: true,
                  context: context,
                  child: RefreshIndicator(// 下拉刷新
                      child: NotificationListener(
                        onNotification: (scrollNotification) {// 監(jiān)聽下拉的狀態(tài)
                          if (scrollNotification is ScrollUpdateNotification &&
                              scrollNotification.depth == 0) {
                            // 優(yōu)化, 防止scrollNotification=0的時候也監(jiān)聽擦耀,只有在ScrollUpdateNotification更新的時候才監(jiān)聽并且只監(jiān)聽ListView的滾動滾動且是列表滾動的時候
                            _onScroll(scrollNotification.metrics.pixels);
                          }
                        },
                        child: _listView,
                      ),
                      onRefresh: _handleRefresh),
                ),
                _appBar,
              ],
            )
        )
    );
  }

  Future<Null> _handleRefresh() async {// Fullter中的異步,返回一個Future
    try {
      HomeModel mode = await HomeDao.fetch();
      setState(() {// 更新Model
        localNavList = mode.localNavList;
        subNavList = mode.subNavList;
        gridNavModel = mode.gridNav;
        salesBoxModel = mode.salesBox;
        bannerList = mode.bannerList;
        _loading = false;// 顯示視圖
      });
    } catch (e) {
      print(e);
      _loading = false;
    }
    return null;
  }

載入布局LoadingContainer:
此Widget由外部isLoading控制顯示隱藏涩堤,內(nèi)部持有子Widget的引用眷蜓,cover控制是否覆蓋整個頁面

@override
 Widget build(BuildContext context) {
   return !cover // // 是否覆蓋整個頁面
       ? isLoading ? _loadingView : child
       : Stack(
           children: <Widget>[child, isLoading ? _loadingView : null],
         );
 }

1. Banner圖

引入flutter_swiper庫。進入到pubspec.yaml文件里添加胎围,同時吁系,引入三方庫也是一樣。圖片通過網(wǎng)絡加載白魂。
pagination: SwiperController 用于控制 Swiper的index屬性, 停止和開始自動播放. 通過 new SwiperController() 創(chuàng)建一個SwiperController實例汽纤,并保存,以便將來能使用福荸。

image.png

Widget get _banner {
    return Container(// Container設置固定高度
      height: 160,
      child: Swiper(//第三方控件
        itemCount: bannerList.length,// 長度
        autoplay: true,// 開啟自動播放
        itemBuilder: (BuildContext context, int index) {
          return GestureDetector(// 返回一個可以點擊的圖片
            onTap: () {
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) {
                  CommonModel model = bannerList[index];
                  return WebView(
                    url: model.url,
                    title: model.title,
                    hideAppBar: model.hideAppBar,
                  );
                }),
              );
            },
            child: Image.network(bannerList[index].icon, fit: BoxFit.fill),
          );
        },
        pagination: SwiperPagination(), // 指示器
      ),
    );
  }

2.AppBar

流程分析:AppBar 在下滑的過程中透明度發(fā)生改變蕴坪,AppBar可以選擇城市,進入搜索頁面。
decoration(裝飾器)DecoratedBox可以在其子widget繪制前(或后)繪制一個裝飾Decoration(如背景背传、邊框呆瞻、漸變等)。主要由外部的appBarAlpha值控制透明度径玖。
控制透明度邏輯:監(jiān)聽ListView滑動的距離痴脾,滑動過程中不斷改變透明值,通過setState()更新視圖梳星。

image.png
Widget get _appBar {
    return Column(
      // 上面輸入赞赖,下面陰影
      children: <Widget>[
        Container(
          decoration: BoxDecoration(
              gradient: LinearGradient(//線性漸變
            // AppBar 漸變遮罩背景, 由透明到
            colors: [Color(0x66000000), Colors.transparent],
            begin: Alignment.topCenter,
            end: Alignment.bottomCenter,
          )),
          child: Container(
            padding: EdgeInsets.fromLTRB(0, 30, 0, 0),
            height: 80.0,
            decoration: BoxDecoration(
                color:
                    Color.fromARGB((appBarAlpha * 255).toInt(), 255, 255, 255)
            ),
            child: SearchBar(
              searchBarType: appBarAlpha > 0.2
                  ? SearchBarType.homeLight
                  : SearchBarType.home,
              inputBoxClick: _jumpToSearch,
              speakClick: _jumpToSpeak,
              defaultText: SEARCH_BAR_DEFAULT_TEXT,
              leftButtonClick: () {},
            ),
          ),
        ),
        Container(
          // 陰影設置
          height: appBarAlpha > 0.2 ? 0.5 : 0,
          decoration: BoxDecoration(
              boxShadow: [BoxShadow(color: Colors.black12, blurRadius: 0.5)]),// 設置陰影
        )
      ],
    );
  }
// 滾動的邏輯
 _onScroll(offset) {
    var alpha = offset / APPBAR_SCROLL_OFFSET;
    if (alpha < 0) {
      // alpha 值的保護
      alpha = 0;
    } else if (alpha > 1) {
      alpha = 1;
    }
    setState(() {
      appBarAlpha = alpha;
    });
    print(appBarAlpha);
  }

SeacherBar
對InputDecoration進行了封裝,擁有多種成員函數(shù)冤灾,是否禁止搜索薯定、按鈕隱藏、背景顏色瞳购、函數(shù)回調(diào)等多種功能。
final void Function() leftButtonClick; 將函數(shù)從其他地方傳入亏推,加大擴展性学赛。
_wrapTap() 封裝函數(shù)對可點擊的按鈕進行封裝
ValueChanged<String> 文本內(nèi)容變換監(jiān)聽,用于改變按鈕的樣式
優(yōu)化:原因:由于每次文本變化需要從網(wǎng)絡拉取數(shù)據(jù)吞杭,可能造成用戶輸入的內(nèi)容不是真正需要顯示的內(nèi)容盏浇。
解決:在網(wǎng)絡請求方法保存keyword。檢查請求來的keyword是否一樣芽狗。檢查Widget重繪的次數(shù)绢掰,并且解決BUG。

_wrapTap(Widget child, void Function() callback) {
  return GestureDetector(
     onTap: () {
       if (callback != null) callback();
     },
     child: child,
   );
 }

  SearchDao.fetch(url, text).then((SearchModel model) {
      // 只有當當前輸入的內(nèi)容與服務端返回的內(nèi)容一致才渲染
      if (model.keyword == keyword) {// 檢驗keyword
        setState(() {
          searchModel = model;
        });
      }
    }).catchError((e) {
      print(e);
    });

3. 卡片布局

布局分成三部分童擎,再將其中一部分分為滴劲,一個大卡片兩個小卡片。
PhysicalModel 實現(xiàn)卡片圓角
FractionallySizedBox:撐滿父布局顾复,F(xiàn)ractionallySizedBox控件會根據(jù)現(xiàn)有空間班挖,來調(diào)整child的尺寸,所以說child就算設置了具體的尺寸數(shù)值芯砸,也不起作用萧芙。

image.png

  @override
  Widget build(BuildContext context) {

    return PhysicalModel(// 
      color: Colors.transparent,
      borderRadius: BorderRadius.circular(6),// 圓角
      clipBehavior: Clip.antiAlias, // 裁切
      child: Column(
        children: _gridNavItems(context),
      ),
    );
  }

4. 底部卡片

頂部是可點擊的圖片與文本,下面是三組卡片假丧,第一組高度較大
Image: BoxFit.fill:會拉伸填充滿顯示空間双揪,圖片本身長寬比會發(fā)生變化,圖片會變形包帚。
width: MediaQuery.of(context).size.width:獲得手機屏幕寬度渔期,需要計算padding

image.png

參考

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末羽德,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子迅办,更是在濱河造成了極大的恐慌宅静,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件站欺,死亡現(xiàn)場離奇詭異姨夹,居然都是意外死亡,警方通過查閱死者的電腦和手機矾策,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進店門磷账,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人贾虽,你說我怎么就攤上這事逃糟。” “怎么了蓬豁?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵绰咽,是天一觀的道長。 經(jīng)常有香客問我地粪,道長取募,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任蟆技,我火速辦了婚禮玩敏,結果婚禮上,老公的妹妹穿的比我還像新娘质礼。我一直安慰自己旺聚,他們只是感情好,可當我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布眶蕉。 她就那樣靜靜地躺著翻屈,像睡著了一般。 火紅的嫁衣襯著肌膚如雪妻坝。 梳的紋絲不亂的頭發(fā)上伸眶,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天,我揣著相機與錄音刽宪,去河邊找鬼厘贼。 笑死,一個胖子當著我的面吹牛圣拄,可吹牛的內(nèi)容都是我干的嘴秸。 我是一名探鬼主播,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼岳掐!你這毒婦竟也來了凭疮?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤串述,失蹤者是張志新(化名)和其女友劉穎执解,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體纲酗,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡衰腌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了觅赊。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片右蕊。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖吮螺,靈堂內(nèi)的尸體忽然破棺而出饶囚,到底是詐尸還是另有隱情,我是刑警寧澤鸠补,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布萝风,位于F島的核電站,受9級特大地震影響莫鸭,放射性物質發(fā)生泄漏。R本人自食惡果不足惜横殴,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一被因、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧衫仑,春花似錦梨与、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至瞄崇,卻和暖如春呻粹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背推溃。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工仇穗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留瓢喉,地道東北人。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓筹燕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子撒踪,可洞房花燭夜當晚...
    茶點故事閱讀 44,678評論 2 354

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

  • 簡書日語學習交流群新版打卡活動第一期第一天 發(fā)布單詞【不明】 不明【ふめい】 1过咬、不明、不詳 2制妄、蠢掸绞、無能 請參與...
    白子童閱讀 370評論 0 1
  • 我女兒剛舉行了幼兒園畢業(yè)匯演,進入了上小學前的假期忍捡。這幾日集漾,想起她的老師、同學們時砸脊,就開始以標準的小孩子的姿勢具篇,哇...
    裸足閱讀 308評論 0 0
  • 提到音響,有的車主喜歡柔中帶勁的孩哑, 有的車主喜歡人聲清晰的栓霜,更有的車主喜歡低音扎實的,每位車主都有不同的音樂風格横蜒,...
    mrz_84fc閱讀 643評論 0 0
  • 1胳蛮、字符串轉換成數(shù)字 +s s-0//減號默認轉數(shù)字 2、數(shù)字轉字符串 123+‘’//只要+號中有一個是字符串則...
    懶羊羊3號閱讀 423評論 0 0
  • 很喜歡韓寒的這一段話: 談戀愛就該經(jīng)歷一下異地戀,體會一下欣喜憂愁無從分享澎蛛,歡笑落淚不能擁抱抚垄,隔著屏幕隔著電話隔著...
    Meet黃婧婧閱讀 1,516評論 10 12