Flutter開(kāi)發(fā) 項(xiàng)目實(shí)戰(zhàn)02

接著上篇

這篇最主要的是:

  1. GridView (flutter的橫向列表胃碾,相對(duì)于iOS的UICollectionView)

  2. httpClient (flutter的網(wǎng)絡(luò)請(qǐng)求,暫時(shí)會(huì)簡(jiǎn)單的數(shù)據(jù)處理悠就,關(guān)于數(shù)據(jù)模型化還沒(méi)未到更快捷的方法,需要硬敲出來(lái),沒(méi)有類似iOS中的YYModel一樣,直接一套)

3. 頁(yè)面的跳轉(zhuǎn)并傳參(上下級(jí)頁(yè)面通常需要傳遞參數(shù)趟径,類似詳情頁(yè),可以減少網(wǎng)絡(luò)請(qǐng)求的次數(shù))

  1. flutter_refresh(flutter的一個(gè)上拉刷新下拉加載的插件癣防,調(diào)用很簡(jiǎn)單舵抹,關(guān)于自定義刷新動(dòng)畫(huà)還需要更多的去了解,順便介紹關(guān)于根據(jù)條件來(lái)動(dòng)態(tài)布局)

1. Flutter的橫向列表GridView

flutter中橫向列表類似iOS中的UICollectionView的是GridView劣砍,開(kāi)發(fā)前我沒(méi)有了解到這個(gè)控件,對(duì)于行數(shù)不多的扇救,我直接使用listview自定義item硬寫(xiě)刑枝,當(dāng)然復(fù)制代碼也是很快的,但是當(dāng)然需要更可塑性的布局方式迅腔∽俺看下面這張圖我的頁(yè)面中的示例。

我的頁(yè)面
image

這個(gè)頁(yè)面總體是個(gè)ListView沧烈,對(duì)應(yīng)的是每個(gè)item掠兄,其中紅框就是個(gè)GridView,以下是創(chuàng)建GridView的代碼


//GridView的創(chuàng)建代碼

doubleItemWidth= ScreenWidth /4.0;

doubleItemHeight=70.0;

var cellItemMiddleInfo =new GestureDetector(

onTap: ()=>{},

child:new Container(

width: ScreenWidth,

child:new Column(

children: [

new Container(

width: ScreenWidth,

height: SmallMiddleHeight *2.0,

color: Colors.white,

child:new GridView.builder(

gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(

mainAxisSpacing:0.0,//豎向間距

//                    crossAxisCount: 4,//橫向Item的個(gè)數(shù)

                      maxCrossAxisExtent: ScreenWidth/4.0,

crossAxisSpacing:0.0,//橫向間距

                      childAspectRatio:(ItemWidth/ItemHeight)

),

primary:false,

itemCount: List2.length,

itemBuilder: MyItemImageText,

)

),

new Divider(height:1.0,),

new Container(

width: ScreenWidth,

height:15.0,

),

new Divider(height:1.0,),

],

)

),

);

//GridView也需要子item锌雀,這是子item的代碼

////////中間部分的操作欄 私密文章 我的收藏 我的喜歡 等

WidgetMyItemImageText(BuildContext context, int index) {

doubleScreenWidth= MediaQuery.of(context).size.width;

doubleItemWidth= ScreenWidth /4.0;

doubleItemHeight=70.0;

var Item=new GestureDetector(

onTap: (){},

child:new Container(

width: ItemWidth,

height: ItemHeight,

//      color: Colors.red,

      child:new Column(

children: [

///頂部 圖片

          new Container(

alignment: Alignment.center,

margin:new EdgeInsets.only(left:10.0, right:10.0, top:14.0),

height:18.0,

child:new Container(

alignment: Alignment.center,

height:18.0,

width:18.0,

child:new Image.asset(List2[index].itemImageSrc),

)

),

//底部的text

          new Container(

alignment: Alignment.center,

margin:new EdgeInsets.only(left:10.0, right:10.0, top:7.0),

height:15.0,

child:new Text(List2[index].downText, style:new TextStyle(fontSize:12.0, color:new Color.fromARGB(255,123,123,123)), softWrap:false, overflow: TextOverflow.ellipsis),

),

],

),

),

);

return Item;

}

工具類

以上就可以實(shí)現(xiàn)一個(gè)橫向的GridView蚂夕,我相信閱覽了代碼后也知道如何使用,其中childAspectRatio屬性是用來(lái)設(shè)置item寬高比的腋逆,如果不設(shè)置默認(rèn)寬高一樣婿牍。

2. Flutter的網(wǎng)絡(luò)請(qǐng)求


ListdataSource;

void _httpClient(var page)async {

var responseBody;

var httpClient =new HttpClient();

var request =await httpClient.getUrl(

Uri.parse("https://www.apiopen.top/satinGodApi?type=1&page=${page}"));

var response =await request.close();

print(page);

if (response.statusCode ==200) {

responseBody =await response.transform(utf8.decoder).join();

ListnewData = jsonDecode(responseBody)["data"];

if(page ==1 &&dataSource !=null) {

dataSource.clear();

}

//更新數(shù)據(jù)

    setState(() {

if(page ==1) {

dataSource = newData;

}else {

for (int a =0; a

dataSource.add(newData[a]);

}

}

});

}else {

print("error");

}

}

還要包含兩個(gè)頭文件哦


import 'dart:io';

import 'dart:convert';

頁(yè)面一進(jìn)去的話在這里調(diào)用


void initState() {

super.initState();

_httpClient(PAGE);

}

其中setState這個(gè)方法刷新dataSource可以刷新頁(yè)面,flutter會(huì)檢測(cè)哪里用到了dataSource就會(huì)刷新那里的頁(yè)面惩歉,關(guān)于數(shù)據(jù)的是數(shù)組直接[index] 是map里取值就直接["key"]等脂,當(dāng)然你可以封裝一個(gè)數(shù)組里面包含返回值的所有key俏蛮,這樣使用的時(shí)候就可以直接dataSource.key.key了,但是我這里沒(méi)有上遥,因?yàn)榫蘼闊┎肌5日业礁咝У姆椒ê笤偃バ薷陌伞?/p>

3. Flutter頁(yè)面的跳轉(zhuǎn)并傳參

在開(kāi)發(fā)中,很多情況下需要傳遞參數(shù)到下級(jí)頁(yè)面粉楚,比如詳情頁(yè)辣恋,外部請(qǐng)求了一次,詳情頁(yè)就沒(méi)有必要再請(qǐng)求一次解幼,可以上級(jí)頁(yè)面?zhèn)鬟^(guò)來(lái)使用抑党。跳轉(zhuǎn)頁(yè)面根據(jù)Flutter的文檔,routes的靈感來(lái)源于reactjs撵摆,routes可以翻譯為路由底靠,可以看到這種routes的思路在目前的設(shè)計(jì)中彼此借鑒,routes的思路不僅在前端流行特铝,比如在vue暑中、reactjs、Angular中用到鲫剿,而且在后端應(yīng)用中也非常成熟鳄逾。

關(guān)于頁(yè)面跳轉(zhuǎn)的代碼


////跳轉(zhuǎn)段子詳情

pushAnotherView(int index){

print(index);

Navigator.of(context).push(

new MaterialPageRoute(

builder: (BuildContext context) {

var data =dataSource[index];

return new JokeDetailPage(mapd: data);

}

)

);

}

////返回按鈕

new FlatButton(

onPressed:(){

Navigator.pop(context);

},

color: Colors.white,

child:new Icon(Icons.keyboard_backspace,color: Colors.blue, ),

),

接下來(lái)看看頁(yè)面之間如何傳參數(shù)


////這是二級(jí)頁(yè)面的接收的寫(xiě)法

class JokeDetailPageextends StatefulWidget {

 JokeDetailPage ({var key,this.mapd}):super(key:key);//接收從上一個(gè)頁(yè)面?zhèn)鱽?lái)的值

 var mapd;

@override

  _JokeDetailPageState createState() =>new _JokeDetailPageState(mapd,mapd);

}

class _JokeDetailPageStateextends State  {
    _JokeDetailPageState(var key,this.mapd);
    var mapd;

  @override
  void dispose() {
      super.dispose();
  }

  void initState() {
      super.initState();
  }

 @override

 Widget build(BuildContext context) {
        return new MaterialApp();
  }

}

我這里傳的是個(gè)var類型的數(shù)據(jù),也可以傳其他數(shù)據(jù)類型的灵莲。在上級(jí)頁(yè)面跳轉(zhuǎn)的時(shí)候就可以有提示了


////跳轉(zhuǎn)段子詳情   其中index是點(diǎn)擊某個(gè)item傳過(guò)來(lái)的 

pushAnotherView(int index){
     print(index);
      Navigator.of(context).push(
          new MaterialPageRoute(
              builder: (BuildContext context) {
                    var data =dataSource[index];
                    return new JokeDetailPage(mapd: data);////這里就可以傳遞參數(shù)了
              }
        )
    );
}

4. flutter_refresh

一個(gè)上拉加載雕凹,下拉刷新的控件。這是個(gè)插件政冻,所以我們需要在pubspec.yaml文件中添加這個(gè)插件及版本號(hào)枚抵,然后運(yùn)行Packages get來(lái)拉到本地來(lái),這個(gè)插件的鏈接地址:flutter_refresh明场。

添加插件

使用方法


////chiild直接就是Refresh 添加頭部尾部刷新方法和UI即可
return new Container(
      child:dataSource!=null ?
      new Refresh(
            onFooterRefresh: onFooterRefresh,
            onHeaderRefresh: onHeaderRefresh,
            child:new ListView.builder(
                  itemCount:dataSource.length,
                  itemBuilder: buildCelljianyouquanItem1,
            )
      ) :
      new Container(child:new Text(tab.text)),
);

// 頂部刷新
Future onHeaderRefresh() {
    return new Future.delayed(new Duration(seconds:2), () {
          setState(() {
                PAGE =1;
                _httpClient(PAGE);
          });
  });
}

// 底部刷新
Future onFooterRefresh()async {
    return new Future.delayed(new Duration(seconds:2), () {
        setState(() {
            PAGE +=1;
            _httpClient(PAGE);
         });
   });
}

以上就可以實(shí)現(xiàn)基本的刷新頁(yè)面了哦汽摹。

下拉刷新
上拉加載

這里圖片加載用了一個(gè)插件transparent_image,占位符淡入圖片苦锨。


child:new FadeInImage.memoryNetwork(
    alignment: Alignment.centerLeft,
    placeholder: kTransparentImage,
    image:dataSource[index]["thumbnail"],
    fit: BoxFit.cover,
)

還要介紹以下根據(jù)條件動(dòng)態(tài)布局逼泣,這個(gè)我找了好久的資料沒(méi)找到,可能找到的方向不對(duì)舟舒,看到代碼后拉庶,原來(lái)如此,也很簡(jiǎn)單魏蔗。就拿下面的一段代碼來(lái)做示列砍的。


return new Container(
  child:dataSource!=null ?
      new Refresh(
          onFooterRefresh: onFooterRefresh,
          onHeaderRefresh: onHeaderRefresh,
          child:new ListView.builder(
          itemCount:dataSource.length,
          itemBuilder: buildCelljianyouquanItem1,
      )
  ):new Container(child:new Text(tab.text)),
);

這里我返回的Container根據(jù)了dataSource來(lái)判斷,如果dataSource有值說(shuō)明可以創(chuàng)建Listview刷新頁(yè)面顯示數(shù)據(jù)了莺治,但是如果為空的話就返回一個(gè)居中的文本廓鞠,顯示正在加載中帚稠。一個(gè)簡(jiǎn)單的三目運(yùn)算就可以完成根據(jù)數(shù)據(jù)來(lái)布局,這種用法貫穿了很多的布局床佳。所以要Get哦滋早。

最后附上Github上的Demo的地址:Demo傳送門(mén)

還有開(kāi)放API的地址:開(kāi)放API

還有學(xué)習(xí)網(wǎng)站:

Flutter中文網(wǎng)

Flutter社區(qū)中文資源

如有不正確的地方幫忙指出,謝謝砌们。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末杆麸,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子浪感,更是在濱河造成了極大的恐慌昔头,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件影兽,死亡現(xiàn)場(chǎng)離奇詭異揭斧,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)峻堰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)讹开,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人捐名,你說(shuō)我怎么就攤上這事旦万。” “怎么了镶蹋?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵成艘,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我贺归,道長(zhǎng)狰腌,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任牧氮,我火速辦了婚禮,結(jié)果婚禮上瑰枫,老公的妹妹穿的比我還像新娘踱葛。我一直安慰自己,他們只是感情好光坝,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布尸诽。 她就那樣靜靜地躺著,像睡著了一般盯另。 火紅的嫁衣襯著肌膚如雪性含。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,784評(píng)論 1 290
  • 那天鸳惯,我揣著相機(jī)與錄音商蕴,去河邊找鬼叠萍。 笑死,一個(gè)胖子當(dāng)著我的面吹牛绪商,可吹牛的內(nèi)容都是我干的苛谷。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼格郁,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼腹殿!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起例书,我...
    開(kāi)封第一講書(shū)人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤锣尉,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后决采,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體自沧,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年织狐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了暂幼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡移迫,死狀恐怖旺嬉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情厨埋,我是刑警寧澤邪媳,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站荡陷,受9級(jí)特大地震影響雨效,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜废赞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一徽龟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧唉地,春花似錦据悔、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至群嗤,卻和暖如春菠隆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工骇径, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留躯肌,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓既峡,卻偏偏與公主長(zhǎng)得像羡榴,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子运敢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

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