flutter引導(dǎo)頁究抓、布局猾担、定時器、網(wǎng)絡(luò)異步數(shù)據(jù)更新

疫情剛好靜下心來回歸過去的工作刺下,博主要開始學(xué)習(xí)flutter绑嘹,博主會邊學(xué)習(xí)邊實戰(zhàn)項目連續(xù)連貫實現(xiàn),大約一周會出一篇橘茉,源碼地址,開源不易圾叼,麻煩動手點星,謝謝捺癞,本開源不做商業(yè)使用夷蚊,里面涉及用到api接口資源等只供學(xué)習(xí),項目開發(fā)會分博客文章髓介,請點擊鏈接到對應(yīng)的文章中瀏覽惕鼓,建議其實萬變不離其中,說到底還是離不開原生唐础,學(xué)習(xí)之前往補充原生知識箱歧,本片主要講的是引導(dǎo)頁矾飞,其中涉及到技術(shù)點層疊布局、相對定位呀邢、容器洒沦、定時器、異步數(shù)據(jù)更新价淌,再次感謝大家能耐心觀看申眼,謝謝!
@[TOC](Flutter 開始征途)

1 布局詳解

1.1 Stack層疊布局

在flutter中層疊布局就是疊加效果蝉衣,如果做過安卓的話括尸,那么就知道FrameLayout,其實就依次往上一層view層疊效果

在這里插入圖片描述

ios 最原始addSubview,其實就是一個層疊布局效果病毡。

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    UIView * view1 = [[UIView alloc]initWithFrame:CGRectMake(20, 40, 200, 200)];
    view1.backgroundColor=[UIColor redColor];
    UIView * view2 = [[UIView alloc]initWithFrame:CGRectMake(10, 10, 100, 100)];
    view2.backgroundColor=[UIColor greenColor];
    [view1 addSubview:view2];
    [self.view addSubview:view1];
}

下面是flutter的實現(xiàn)濒翻,children包含子組件數(shù)組,依次視圖疊加效果啦膜,而Positioned是用來做絕對位置的有送,左右頭底,四個點需要自己計算適配哦僧家。

在這里插入圖片描述

1.2 Align 相對布局詳解

1.2.1 安卓相對布局

在安卓中大家應(yīng)該很熟悉RelativeLayout,這可是我們安卓最常用最無敵布局神器雀摘,再復(fù)雜的業(yè)務(wù)都是浮云。

布局 方向
layout_centerHorizontal 水平居中
layout_alignParentRight 右對齊
layout_alignParentLeft 左對齊
layout_alignParentTop 頂部對齊
layout_alignBottom 居底部對齊
layout_centerInParent 居中
layout_centerVertical 豎向?qū)R

1.2.2 ios相對布局

ios我們開發(fā)的時候啸臀,我們用的Autolayout布局届宠,解析如下:

UIView *subView = [[UIView alloc]init];
subView.backgroundColor = [UIColor greenColor];
[self.view addSubview:subView];
subView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1. constant:150]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeHeight multiplier:0.3 constant:0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:0.3 constant:0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1. constant:100]];

上面方法參數(shù)說明:
第一個參數(shù):指定約束左邊的視圖view1
第二個參數(shù):指定view1的屬性attr1
第三個參數(shù):指定左右兩邊的視圖的關(guān)系relation
第四個參數(shù):指定約束右邊的視圖view2
第五個參數(shù):指定view2的屬性attr2
第六個參數(shù):指定一個與view2屬性相乘的乘數(shù)multiplier
第七個參數(shù):指定一個與view2屬性相加的浮點數(shù)constant
依據(jù)的公式是:view1.attr1 = view2.attr2*multiplier +constant

布局 方向
NSLayoutAttributeLeft 視圖的左邊
NSLayoutAttributeRight 視圖的右邊
NSLayoutAttributeTop 視圖的上邊
NSLayoutAttributeBottom 視圖的下邊
NSLayoutAttributeLeading 視圖的前邊
NSLayoutAttributeTrailing 視圖的后邊
NSLayoutAttributeWidth 視圖的寬度
NSLayoutAttributeHeight 視圖的高度
NSLayoutAttributeCenterX 視圖的中點的X值
NSLayoutAttributeCenterY 視圖中點的Y值
NSLayoutAttributeBaseline 視圖的基準線
NSLayoutAttributeNotAnAttribute 無屬性

NSLayoutRelation的類型:
NSLayoutRelationLessThanOrEqual 關(guān)系小于或等于
NSLayoutRelationEqual 視圖關(guān)系等于
NSLayoutRelationGreaterThanOrEqual 視圖關(guān)系大于或等于
這里要說明一下烁落,設(shè)置約束之前必須要求確保子視圖添加到了父視圖上了(如:[self.view addSubview:subView]),并且被約束的視圖的translatesAutoresizingMaskIntoConstraints = NO,不然就會發(fā)生程序crash乘粒。

1.2.3 flutter Align相對布局

Align 組件可以調(diào)整子組件的位置,并且可以根據(jù)子組件的寬高來確定自身的的寬高伤塌,定義如下:
首先你要在外部套一個容器灯萍,或者像安卓要套一個RelativeLayout一樣,區(qū)別目前么發(fā)現(xiàn)如何自適應(yīng)每聪,必須設(shè)置區(qū)域大小旦棉。

布局 方向
Alignment.topLeft 頭部左對齊
Alignment.topRight 頭部右對齊
Alignment.topCenter 頭部居中
Alignment.centerLeft 居中左對齊
Alignment.centerRight 居中右對齊
Alignment.center 居中對齊
Alignment.bottomLeft 底部左對齊
Alignment.bottomCenter 底部居中
Alignment.bottomRight 底部右對齊
new Positioned(
            child: Container(
              child: Align(
                child: Stack(
                  alignment: Alignment.center,
                  children: <Widget>[
                    Image.asset('images/splash_confirm.png'),
                    Text(
                      "立即開啟",
                      style: TextStyle(
                          fontSize: 12,
                          color: Colors.white,
                          fontFamily: 'Raleway',
                          //2.不繼承默認樣式
                          decorationStyle: TextDecorationStyle.dashed),
                    )
                  ],
                ),
                alignment: Alignment.bottomCenter,
              ),
              margin: EdgeInsets.only(bottom: 100),
            ),
            height: pageTotalSize > 0 && (pageViewIndex == pageTotalSize - 1)
                ? height
                : 0,
            width: width)

alignment : 需要一個AlignmentGeometry類型的值,表示子組件在父組件中的起始位置药薯。
AlignmentGeometry 是一個抽象類绑洛,它有兩個常用的子類:Alignment和 FractionalOffset,我們將在下面的示例中詳細介紹童本。
widthFactor和heightFactor是用于確定Align 組件本身寬高的屬性真屯;
它們是兩個縮放因子,會分別乘以子元素的寬穷娱、高绑蔫,最終的結(jié)果就是Align 組件的寬高运沦。如果值為null,則組件的寬高將會占用盡可能多的空間配深。

2 定時器

啟動頁會有定時器携添,定時幾秒后操作,下面會舉例說明安卓篓叶、ios烈掠、flutter實現(xiàn)不同。

2.1 安卓定時器

第一種方式
Timer timer = new Timer(); //創(chuàng)建一個定時器對象
TimerTask task = new TimerTask()
timer.schedule(task,0,10000); //啟動定時器
第二種方式
//參數(shù)1:計時總時間澜共,參數(shù)2:每次扣除時間數(shù)

CountDownTimer cdt = new CountDownTimer(10000, 100)
          {  
                  @Override  
                  public void onTick(long millisUntilFinished)
                  {  
                  }  
                  @Override  
                  public void onFinish() {  
                  } 
         }; 
         cdt.start(); 

其它方式 alarmService向叉、thread、Handler嗦董。

2.2 ios定時器

第一種

 NSTimer *timer = [NSTimer timerWithTimeInterval:2 target:self selector:@selector(test) userInfo:nil repeats:YES];
    // 將定時器添加到runloop中母谎,否則定時器不會啟動
    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
    // 停止定時器
    [timer invalidate];

第二種

// 創(chuàng)建displayLink
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(test:)];
// 將創(chuàng)建的displaylink添加到runloop中,否則定時器不會執(zhí)行
[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

// 停止定時器
[displayLink invalidate];
 displayLink = nil;

2.3 flutter 定時器

Timer定時器記得一定要在initState京革,這個函數(shù)就是初始化狀態(tài)奇唤,你就可以理解為安卓的onCreate()生命周期、ios的initWithCoder狀態(tài)一樣匹摇,build就是一個構(gòu)建widget咬扇,其實就可以理解為安卓xml,但是這里有很大區(qū)別廊勃,就是更新ui懈贺、初始化、initState()坡垫、didUpdateWidget()梭灿、setState()、didChangeDependencies()都會調(diào)用哦冰悠,當(dāng)然布局上更新的數(shù)據(jù)怎么做堡妒,一定是在build構(gòu)建寫對應(yīng)數(shù)據(jù)變量,其實思想就跟mvvm溉卓,數(shù)據(jù)驅(qū)動刷新ui一樣皮迟。

@override
  void initState() {
    // TODO: implement initState
    super.initState();
    splashBuilder = fetchPost();
    initCountDown();
    WidgetsBinding.instance.addObserver(this);
  }
initCountDown() {
    // 只在倒計時結(jié)束時回調(diào)
    Timer.periodic(new Duration(seconds: 1), (timer) {
      if (timer.tick == 5) {
        setState(() {
          nextStr = '跳過';
        });
        timer.cancel();
        print(nextStr);
      } else {
        setState(() {
          nextStr = '${countTime--}s跳過';
        });
        print(nextStr);
      }
    });
  }
new Positioned(
            child: new GestureDetector(
              child: new Container(
                padding: const EdgeInsets.only(
                    left: 10, top: 2, right: 10, bottom: 2),
                decoration: new ShapeDecoration(
                    color: !isClicking1 ? Colors.white : Color(0xff898989),
                    shape: StadiumBorder(
                        side: BorderSide(
                            color: Color(0xff898989),
                            style: BorderStyle.solid,
                            width: 1))),
                child: Text(nextStr),
              ),
              onTap: () {
                print('onTap 跳過');
              },
              onTapUp: (TapUpDetails) {
                print('onTapUp 跳過');
                upDataButtonState(false);
              },
              onTapDown: (TapUpDetails) {
                print('onTapDown 跳過');
                upDataButtonState(true);
              },
              onTapCancel: () {
                print('onTapCancel 跳過');
                upDataButtonState(false);
              },
            ),
            top: 10 + statebar_height,
            right: 10)

3 網(wǎng)絡(luò)異步更新

3.1 網(wǎng)絡(luò)使用詳解

目前在flutter使用最多就是Dio庫,在安卓都是用的是Reftrofit,ios AFNetWork桑寨,好像git有個flutter的reftroft對應(yīng)插件伏尼。dio鏈接

在這里插入圖片描述

在這里插入圖片描述

首先引用dio插件,我們要做一個啟動頁就要有網(wǎng)絡(luò)申請尉尾,直接上dio代碼爆阶,get獲取圖片集合,然后網(wǎng)絡(luò)解析加載。

 Future<SplashEntityEntity> fetchPost() async {
    var dio = Dio();
    Response response;
    response = await dio
        .get(WanAndroidApi.OtherCategory, queryParameters: {"type": 1});
//    print(JsonConvert.fromJsonAsT<SplashEntityEntity>(response.data)
//        .result
//        .elementAt(0)
//        .album10001000);
    return JsonConvert.fromJsonAsT<SplashEntityEntity>(response.data);
  }

3.2 解析數(shù)據(jù)詳解

3.2.1 官方推薦解析

首先扰她,打開JSON to Dart兽掰,JSON to Dar
如下圖所示

在這里插入圖片描述

Map splashMap = JSON.decode(json);
var splash = new Splash.fromJson(userMap);
print('Howdy, ${splash.code}!');
print('We sent the verification link to ${splash.message}.');

3.2.2 FlutterJsonBeanFactory插件

搜索安卓插件,然后重啟工具徒役,這下可以愉快玩耍哦孽尽。


在這里插入圖片描述

右鍵會有一個插件,然后讓你一件生產(chǎn)對應(yīng)的dart解析文件哦忧勿。


在這里插入圖片描述

在這里插入圖片描述

解析就是一行代碼
JsonConvert.fromJsonAsT<SplashEntityEntity>(response.data)

4 異步

當(dāng)我們訪問接口的時候杉女,那么操作肯定需要異步,一邊訪問請求一邊給個進度條鸳吸,這樣體驗會更好熏挎,異步操作很重要,在flutter中異步很簡單晌砾,就是靠FutureBuilder和future配合坎拐,原生我們都是異步線程,然后刷新ui會切主線程刷新养匈。

Future<SplashEntityEntity> fetchPost() async {
    var dio = Dio();
    Response response;
    response = await dio
        .get(WanAndroidApi.OtherCategory, queryParameters: {"type": 1});
//    print(JsonConvert.fromJsonAsT<SplashEntityEntity>(response.data)
//        .result
//        .elementAt(0)
//        .album10001000);
    return JsonConvert.fromJsonAsT<SplashEntityEntity>(response.data);
  }

FutureBuilder<SplashEntityEntity>(
            future: splashBuilder,
            builder: (BuildContext content, AsyncSnapshot async) {
              if (async.connectionState == ConnectionState.done) {
                print("success");
                return getPageView(async.data);
              } else {
                print("loading===");
                return Container(
                  height: 100,
                  width: 100,
                  alignment: Alignment.center,
                  child: CircularProgressIndicator(
                    backgroundColor: Colors.blue,
                    valueColor: AlwaysStoppedAnimation(Colors.blue),
                  ),
                );
                return CircularProgressIndicator(strokeWidth: 1);
              }
            },
          )
  • future:FutureBuilder依賴的Future哼勇,通常是一個異步耗時任務(wù)。
  • initialData:初始數(shù)據(jù)呕乎,用戶設(shè)置默認數(shù)據(jù)积担。
  • builder:這里對應(yīng)異步操作的時候?qū)?yīng)ui組件,其實都是wiget,注意網(wǎng)絡(luò)申請要放在初始化中操作猬仁,如果有定時器的話帝璧,setState更新狀態(tài)話,就會一直走build.

5 事件講解

首先這里要講的事件湿刽,在flutter簡直無法理解的烁,不知道創(chuàng)造這個人是怎么想的,萬物都是Widget,事件怎么能是widget叭爱,這真是無限地獄嵌套撮躁,代碼如下:

5.1 Listener事件

Listener(
  child: Container(
    alignment: Alignment.center,
    color: Colors.blue,
    width: 300.0,
    height: 150.0,
    child: Text(_event?.toString()??"",style: TextStyle(color: Colors.white)),
  ),
  onPointerDown: (PointerDownEvent event) => setState(()=>_event=event),
  onPointerMove: (PointerMoveEvent event) => setState(()=>_event=event),
  onPointerUp: (PointerUpEvent event) => setState(()=>_event=event),
)
事件 介紹
onPointerDown 按下
onPointerUp 抬起時觸發(fā)
onPointerCancel 取消觸摸時觸發(fā)
onPointerMove 移動時觸發(fā)

5.2 手勢事件

手勢這個都是外面包一個漱病,其實這種涉及模式還能理解买雾,需要就外面擴展,不需要就不用寫杨帽,但是點擊事件listener完全不理解嘔吐漓穿。

GestureDetector(
            child: CircleAvatar(child: Text("A")),
            //垂直方向拖動事件
            onVerticalDragUpdate: (DragUpdateDetails details) {
              setState(() {
                _top += details.delta.dy;
              });
            }
          )
事件 介紹
onTapUp 點擊抬起
onTapDown 點擊按下
onTapCancel 取消觸摸時觸發(fā)
onTap 點擊回調(diào)
-------- -----
onDoubleTap 雙擊
-------- -----
onPanDown 指針已接觸屏幕并可能開始移動
onPanStart 指針已經(jīng)接觸屏幕并開始移動
onPanUpdate 與屏幕接觸并移動的指針再次移動
onPanEnd 先前與屏幕接觸并移動的指針不再與屏幕接觸,并且當(dāng)它停止接觸屏幕時以特定速度移動
onPanCancel 先前觸發(fā) onPanDown 的指針未完成

6.效果圖

在這里插入圖片描述
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末注盈,一起剝皮案震驚了整個濱河市晃危,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖僚饭,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件震叮,死亡現(xiàn)場離奇詭異,居然都是意外死亡鳍鸵,警方通過查閱死者的電腦和手機苇瓣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來偿乖,“玉大人击罪,你說我怎么就攤上這事√靶剑” “怎么了媳禁?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長画切。 經(jīng)常有香客問我竣稽,道長,這世上最難降的妖魔是什么霍弹? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任丧枪,我火速辦了婚禮,結(jié)果婚禮上庞萍,老公的妹妹穿的比我還像新娘拧烦。我一直安慰自己,他們只是感情好钝计,可當(dāng)我...
    茶點故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布恋博。 她就那樣靜靜地躺著,像睡著了一般私恬。 火紅的嫁衣襯著肌膚如雪债沮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天本鸣,我揣著相機與錄音疫衩,去河邊找鬼。 笑死荣德,一個胖子當(dāng)著我的面吹牛闷煤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播涮瞻,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼鲤拿,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了署咽?” 一聲冷哼從身側(cè)響起近顷,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后窒升,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缀遍,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年饱须,在試婚紗的時候發(fā)現(xiàn)自己被綠了瑟由。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,872評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡冤寿,死狀恐怖歹苦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情督怜,我是刑警寧澤殴瘦,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站号杠,受9級特大地震影響蚪腋,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜姨蟋,卻給世界環(huán)境...
    茶點故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一屉凯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧眼溶,春花似錦悠砚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至绰筛,卻和暖如春枢泰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背铝噩。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工衡蚂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人骏庸。 一個月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓毛甲,卻偏偏與公主長得像,于是被迫代替她去往敵國和親敞恋。 傳聞我的和親對象是個殘疾皇子丽啡,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,876評論 2 361