Flutter仿照airbnb建立app

github地址:https://github.com/GainLoss/flutter-appreact

1、基礎android

flutter是谷歌公司開發的開源免費的UI框架,用dart語言實現的,能夠實現跨平臺,一套代碼能夠在Android Ios Windows Max Linux系統運行;使用120fps,基於GPU渲染;ios

1.Widgetgit

在flutter中一切都是Widget(和react裏面一切都是組件好像),文字 圖片 甚至路由都是Widget;github

flutter的底層架構(在flutter官網上有)json

1.主題風格:網絡

咱們的主題風格能夠分爲Material和Cupertino是兩種風格的主題包(前者是android後者是ios),風格是能夠選擇的,你也能夠直接用基礎的組件也是能夠的;架構

基礎組件:https://flutterchina.club/widgets/app

Material:https://flutterchina.club/widgets/material/框架

Cupertino:https://flutterchina.club/widgets/cupertino/

Text 文本

Text(
  '文本',
  style:TextStyle(fontSize:10.0,color:Colors.red,fontWeight:FontWeight[500],fontFamily:'字體類型'),//文本類型顏色之類的
  textAlign:TextAlign.center,//文本居中
  maxLines:2,//最多顯示幾行
    textDirection:TextDirection.rtl,//文本方向
    overflow:TextOverflow.ellipsis,//用省略號結尾
    softWrap:false,//是否自動換行
    textScaleFactor:20.0,//字體顯示倍率
    locale//區域設置
) 

Image 圖片

方法 釋義
Image() ImageProvider中獲取圖片,從本質上看,下面的幾個方法都是他的具體實現。
Image.asset(String name) AssetBundler中獲取圖片
Image.network(String src) 顯示網絡圖片
Image.file(File file) File中獲取圖片
Image.memory(Uint8List bytes) Uint8List中顯示圖片

  能夠有這幾種獲取圖片的方法,那麼裏面數據主要有哪幾個呢

 Image(
      width:10.0,
      height:10.0,
      color: Colors.greenAccent,
      colorBlendMode: BlendMode.colorBurn,//和color混合使
      alignment: Alignment.center, //居中
      repeat: ImageRepeat.noRepeat//重複
 )

Icon 圖標 官方圖標:https://material.io/tools/icons/?icon=favorite_border&style=baseline

Icon(
  Icons.ac_unit,
  color:Colors.red,
  size:10.0,
)

TextField 輸入框

TextField(
 TextEditingController controller, //控制正在編輯的文本
 FocusNode focusNode, //是否具備鍵盤焦點
 InputDecoration decoration: const InputDecoration(), //樣式
 TextInputType keyboardType,//鍵盤類型
 TextInputAction textInputAction, //控制鍵盤的功能鍵 指enter鍵,好比此處設置爲next時,enter鍵 顯示的文字內容爲 下一步
 TextStyle style, //文字樣式
 TextAlign textAlign: TextAlign.start, //文字位置
 TextDirection textDirection, //文字下劃線
 bool autofocus: false, //是否自動獲取焦點
 bool obscureText: false, //隱藏文本輸入內容 用 圓點 符號代替
 bool autocorrect: true, //是否自動更正
 int maxLines: 1,//顯示行數 
 int maxLength, //限制長度
 bool maxLengthEnforced: true, //若是這個爲false那麼maxLength設置了也沒有用
 onChanged:(){},//改變事件 
 onEditingComplete,//編輯完成事件
 onSubmitted, //提交事件
 inputFormatters, //限制輸入的文字的格式
 bool enabled, //是否可編輯
 double cursorWidth: 2.0,//光標寬度 
 Radius cursorRadius, //光標圓角
 Color cursorColor,//光標顏色
 Brightness keyboardAppearance, 
 EdgeInsets scrollPadding: const EdgeInsets.all(20.0), 
 DragStartBehavior dragStartBehavior: DragStartBehavior.down, 
 bool enableInteractiveSelection, 
 onTap:(){},//點擊事件 
)

Row:行 Column:列(若是你的內容超出了Row或者column的寬度或者高度,那麼會報錯頁面會顯示黃黑條紋,證實溢出了)

 Row(
    Key key, 
    MainAxisAlignment mainAxisAlignment: MainAxisAlignment.start, //主軸的對齊方向 水平是主軸
    MainAxisSize mainAxisSize: MainAxisSize.max, //佈局的寬高值
    CrossAxisAlignment crossAxisAlignment: CrossAxisAlignment.center, //非主軸的對齊方式
    TextDirection textDirection, //Row 子級的排列順序
    VerticalDirection verticalDirection: VerticalDirection.down,//Column 子級的排列順序 
    TextBaseline textBaseline, //子組件對齊的,只不過對齊的是字符的基線
    List<Widget> children: const <Widget> []//放置本身
)

Flex:彈性佈局容許子widget按照必定比例來分配父容器空間(和Row、Column相似)

 Flex(
  Key key, 
  Axis direction, //樣式 邊框之類的
  MainAxisAlignment mainAxisAlignment: MainAxisAlignment.start, 
  MainAxisSize mainAxisSize: MainAxisSize.max, 
  CrossAxisAlignment crossAxisAlignment: CrossAxisAlignment.center, 
  TextDirection textDirection, 
  VerticalDirection verticalDirection: VerticalDirection.down, 
  TextBaseline textBaseline, 
  List<Widget> children: const <Widget> []//子級
)

Expand:能夠按比例「擴伸」Row、Column和Flex子widget所佔用的空間。

Expanded(
  Key key, 
  int flex: 1, 
  Widget child
)

Wrap和Flow:支持流式佈局,能夠在要溢出的時候自動換行(Wrap對比Row Flow對比Column Flow儘可能少用,由於太過複雜了)

Wrap(
 Key key, 
 Axis direction: Axis.horizontal, 
 WrapAlignment alignment: WrapAlignment.start,
 double spacing: 0.0, //主軸方向子widget的間距
 WrapAlignment runAlignment: WrapAlignment.start, 
 double runSpacing: 0.0, //縱軸方向的間距
 WrapCrossAlignment crossAxisAlignment: WrapCrossAlignment.start, 
 TextDirection textDirection, 
 VerticalDirection verticalDirection: VerticalDirection.down, 
 List<Widget> children: const <Widget> []//子級
)

Stack Positioned :層疊(常常一塊使用)

Stack(
   Key key, 
   AlignmentGeometry alignment: AlignmentDirectional.topStart, //如何去對齊沒有定位
   TextDirection textDirection, 
   StackFit fit: StackFit.loose, //用於決定沒有定位的子widget如何去適應Stack的大小
   Overflow overflow: Overflow.clip, //決定如何顯示超出Stack顯示空間的子widget
   List<Widget> children:[
     Image('src'),
     Positioned(
       Key key, 
       double left, 
       double top, 
       double right, 
       double bottom, 
       double width, 
       double height, 
       Widget child
     )
  ]
)

Container:容器

          Container(
            Key key, 
            AlignmentGeometry alignment,//子級對齊 
            EdgeInsetsGeometry padding, 
            Color color, //顏色
            Decoration decoration,// 背景裝飾
            Decoration foregroundDecoration, //前景裝飾
            double width, 
            double height, 
            BoxConstraints constraints, //容器大小的限制條件
            EdgeInsetsGeometry margin, 
            Matrix4 transform, //變換
            Widget child
          )

ConstrainedBox:限制容器

ConstrainedBox(
  Key key, 
  constraints: BoxConstraints(
    minWidth: double.infinity, //寬度儘量大
    minHeight: 50.0 //最小高度爲50像素
  ),
  Widget child
)

BoxDecoration:裝飾容器

BoxDecoration(
  Color color, //顏色
  DecorationImage image, //圖片
  BoxBorder border, //邊框
  BorderRadiusGeometry borderRadius, //圓角
  List<BoxShadow> boxShadow, //陰影
  Gradient gradient, 
  BlendMode backgroundBlendMode, 
  BoxShape shape: BoxShape.rectangle
)

ListView:水平列表

ListView(
  Key key, 
  Axis scrollDirection: Axis.vertical, //水平列表仍是垂直列表
  bool reverse: false, //翻轉
  ScrollController controller, 
  bool primary, 
  ScrollPhysics physics, 
  bool shrinkWrap: false, //是否根據子widget的總長度來設置ListView的長度
  EdgeInsetsGeometry padding, 
  double itemExtent, //控制子控件在滾動方向上的長度,因此它跟scrollDirection是密切相關的
  bool addAutomaticKeepAlives: true, 
  bool addRepaintBoundaries: true, 
  bool addSemanticIndexes: true, 
  double cacheExtent, 
  List<Widget> children: const <Widget> [], 
  int semanticChildCount, 
  DragStartBehavior dragStartBehavior: DragStartBehavior.down
)

GridView:相似表格的那種佈局

GridView(
  Key key, 
 gridDelegate:SliverDelegateWithFixedCrossAxiaCount(
  crossAxisCount:2,//橫軸兩個子級
  childAspextRatio:1.0//寬高比爲1
  mainAxisSpacing:0.0,//主軸間隔
  crossAxisSpacing:0.0,//橫軸間隔
), Axis
scrollDirection: Axis.vertical, //水平仍是垂直 bool reverse: false, //翻轉 ScrollController controller, bool primary, ScrollPhysics physics, bool shrinkWrap: false, EdgeInsetsGeometry padding, SliverGridDelegate gridDelegate, bool addAutomaticKeepAlives: true, bool addRepaintBoundaries: true, bool addSemanticIndexes: true, double cacheExtent, List<Widget> children: const <Widget> [], int semanticChildCount )

GestureDetector:手勢(交互事件在這裏面都有)

GestureDetector(
  Key key, 
 Widget child, (TapDownDetails) → void onTapDown, (TapUpDetails) → void onTapUp, () → void onTap, () → void onTapCancel, () → void onDoubleTap, () → void onLongPress, () → void onLongPressUp, (GestureLongPressDragStartDetails) → void onLongPressDragStart, (GestureLongPressDragUpdateDetails) → void onLongPressDragUpdate, (GestureLongPressDragUpDetails) → void onLongPressDragUp, (DragDownDetails) → void onVerticalDragDown, (DragStartDetails) → void onVerticalDragStart, (DragUpdateDetails) → void onVerticalDragUpdate, (DragEndDetails) → void onVerticalDragEnd, () → void onVerticalDragCancel, (DragDownDetails) → void onHorizontalDragDown, (DragStartDetails) → void onHorizontalDragStart, (DragUpdateDetails) → void onHorizontalDragUpdate, (DragEndDetails) → void onHorizontalDragEnd, () → void onHorizontalDragCancel, (ForcePressDetails) → void onForcePressStart, (ForcePressDetails) → void onForcePressPeak, (ForcePressDetails) → void onForcePressUpdate, (ForcePressDetails) → void onForcePressEnd, (DragDownDetails) → void onPanDown, (DragStartDetails) → void onPanStart, (DragUpdateDetails) → void onPanUpdate, (DragEndDetails) → void onPanEnd, () → void onPanCancel, (ScaleStartDetails) → void onScaleStart, (ScaleUpdateDetails) → void onScaleUpdate, (ScaleEndDetails) → void onScaleEnd, HitTestBehavior behavior, bool
excludeFromSemantics: false, DragStartBehavior dragStartBehavior: DragStartBehavior.down )

StatelessWidget和StatefulWidget

1.StatelessWidget:無中間狀態變化的widget,須要更新展現內容就得經過從新new,flutter推薦儘可能使用StatelessWidget

2.StatefullWidget:存在中間狀態變化,那麼問題來了,widget不是都immutable的,狀態變化存儲在哪裏?flutter 引入state的類用於存放中間態,經過調用state.setState()進行此節點及如下的整個子樹更新

 

2、注意

1.在dart中若是須要將變量變成私有的能夠在變量名字前面加下劃線 _name 就能夠了;

2.有的組件具備點擊效果好比LnkWall 有一個onTap表示點擊,可是有的並無點擊函數。因此咱們能夠把這個組件放到手勢裏面;

3、理解

1.幾種移動端開發的技術對比

  React Native   是接近原生;               須要些適配代碼;         60fps(幀)

  Html5    就是嵌入頁面;           須要適配代碼;   

  Flutter    能夠和原生開發一致甚至超過原生;    不須要直接一套代碼就能夠了;  120fps (幀) 基於C++開發 原生的是基於Java開發的

2.引入dart文件或者包

<1>.import 組件路徑 show 須要導入的組件名稱;//本地組件 只引入組件名字的,若是沒有寫名字那麼就是所有引入

<2>.import 'package:包名稱';//要引入的dart文件

  在pubspec.yaml文件中將包的版本寫上,就能夠了

1 dependencies:
2   flutter:
3     sdk: flutter
4   cupertino_icons: ^0.1.2
5   http : ^0.12.0
6   dio: ^2.1.0
7   date_range_picker: ^1.0.5

<3>.一個dart文件做爲另外一個文件的一部分

在父中:part './book/Featured.dart';

在子中:part of '../book.dart';

3.數據交互

第一種方法

import 'package:http/http.dart' as http;//包
import 'dart:convert';//包
class GetData extends StatefulWidget{
  _StateGetData createstate()=>_StateGetData() 
}
class _StateGetData extends State<GetData>{
    Future _getDataInfo() async{
    final url=Uri.http('10.0.2.2:8081','/home',{'mark':'春季特惠房間','address':widget.mark});
    final result=await http.get(url);
    setState((){
      data=json.decode(result.body).toList();
    });
  }
  @override
  void initState(){
    super.initState();
    _getDataInfo();
  }
  Widget build(BuildContext context){
     return Container()    
  }    
}

第二種方法

import 'package:http/http.dart' as http;//包
import 'dart:convert';//包
class GetData extends StatefulWidget{
  _StateGetData createstate()=>_StateGetData() 
}
class _StateGetData extends State<GetData>{
    _getDataInfo(){
    final url=Uri.http('10.0.2.2:8081','/home',{'mark':'春季特惠房間','address':widget.mark});
    final result=http.get(url);
    return result
  }
  @override
  Widget build(BuildContext context){
    FutureBuilder(
      future:_getDataInfo(),
      builder:(BuildContext context,snap){
        return snap.data
      }
    )
     return Container()    
  }    
}

4.路由

main.dart

return new MaterialApp(
      title: 'Flutter Demo',
      home: new MyHomePage(title: '應用程序首頁'),
      routes: <String, WidgetBuilder> {
        '/a': (BuildContext context) => new MyPage(title: 'A 頁面'),
        '/b': (BuildContext context) => new MyPage(title: 'B 頁面'),
        '/c': (BuildContext context) => new MyPage(title: 'C 頁面')
      },
);

1.page1-page2

page1

Navigator.pushNamed(context,'/page2')

2.page1-page2帶參數

page1

Navigator.of((context).push(MaterialPageRoute(
builder: (context) {
return new Page2("傳入跳轉參數");
}
));

3.page2-page1帶參數

page2

Navigator.of(context).pop("我是來自dymamic 關閉的返回值");

 5.flutter底層渲染

咱們在開發android或者ios的時候用的語言是不同,可是最終的圖形計算和繪製都是由相應的硬件來完成,而直接操做硬件的指令一般都會有操做系統屏蔽,應用開發者一般不會直接面對硬件,操做系統屏蔽了這些底層硬件操做後會提供一些封裝後的API供操做系統之上的應用調用,可是對於應用開發者來講,直接調用這些操做系統提供的API是比較複雜和低效的,由於操做系統提供的API每每比較基礎。

Flutter的原理正是如此,它提供了一套Dart API,而後在底層經過OpenGL這種跨平臺的繪製庫(內部會調用操做系統API)實現了一套代碼跨多端。因爲Dart API也是調用操做系統API,因此它的性能接近原生。

6.Element和BuildContext的區別

根據Widget生成Element,而後建立相應的RenderObject並關聯到Element.renderObject屬性上,最後再經過RenderObject來完成佈局排列和繪製。

4、資料

1.官網:https://flutter.dev/

2.中文網站:https://flutterchina.club/

3.dart package:https://pub.dartlang.org/

4.Icon:https://material.io/tools/icons/?icon=favorite_border&style=baseline

5.數據能夠放在firebase

相關文章
相關標籤/搜索