Flutter學習總結(十二、Flutter基本組件第二部分)

Flutter基本組件第二部分

一起從0開始學習Flutter!

上一篇我們瞭解了AppBar,FloatingActionButton,Text,BottomNavigationBar的基本使用,這篇將會介紹TabBar,TabBarView,Image

1.TabBar

也是我們經常使用的控件,在現在的APP中越來越多的信息需要展示的時候,tabbar的出現可以解決頁面冗長無序的問題,可以根據內容的分類進行劃分tab。

const TabBar({
    Key key,
    @required this.tabs,//參照下面詳解
    this.controller,//參照下面詳解
    this.isScrollable = false,//如果tab很多是否可以滾動顯示,如果是False會平分寬度以全部顯示,如果是True則會居中顯示全部的tab
    this.indicatorColor,//在選中的tab下方的指示器顏色
    this.indicatorWeight = 2.0, //指示器的高度
    this.indicatorPadding = EdgeInsets.zero,//指示器底部添加的padding
    this.indicator,//設定指示器的樣式,默認的爲UnderlineTabIndicator,我們可以仿照它寫自己想要的指示器的樣式
    this.indicatorSize,//參照下面詳解
    this.labelColor,//選中label的顏色
    this.labelStyle,//選中label的樣式,傳入的是TextStyle
    this.labelPadding,//可以給label加padding,padding的添加方式也是通過EdgeInsets類來添加。
    this.unselectedLabelColor,//沒有選中的label的顏色
    this.unselectedLabelStyle,//沒有選中的label的樣式,傳入的是TextStyle
    this.dragStartBehavior = DragStartBehavior.start,
    this.onTap,//點擊事件響應,調用給返回點擊的位置position
  }) 

tabs
需要添加的tab元素,也就是根據需要設定我們要顯示的頭部。會添加一組Tab信息,先看下單個的Tab。

const Tab({
    Key key,
    this.text,//想要顯示的標題文字
    this.icon,//可以自己添加Icon
    this.child,//擴展的其他的想要添加的內容
  }) 

controller
我們需要傳入TabController對象,根據名字也看得出來是控制Tab的一個控制器,看下如何創建該對象。

TabController({ 
int initialIndex = 0,//初始化時默認選中的位置
@required this.length, //Tab要顯示的數量
@required TickerProvider vsync //控制Tab和TabView的同步,我們可以直接讓創建Controller的類繼承或者with SingleTickerProviderStateMixin
})

創建一個controller_controller = TabController(vsync: this, length: tabs.length);這裏的this也就是當前類對象,我們還需要讓當前類繼承自SingleTickerProviderStateMixin,我們可以這樣寫:class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin 還記得這個with關鍵字吧,如果忘記了可以回去看下Dart的類繼承 裏面的介紹。
indicatorSize
指示器的寬度
TabBarIndicatorSize.tab 和tab整個的寬度一致
TabBarIndicatorSize.label 和tab上面文字的寬度一致

2.TabBarView

是和TabBar一起搭配使用的,可以根據選擇的tab顯示不同的頁面。

const TabBarView({
    Key key,
    @required this.children,
    this.controller,
    this.physics,
    this.dragStartBehavior = DragStartBehavior.start,
  })

children
也即是我們需要添加的TabBarView的佈局頁面,這裏可以根據需要添加我們前面說到的容器等組件。給出一個簡單的示例:

TabBarView(
   controller: _controller,
   children: tabs.map(
             (Tab tab) => Container(
                          child: Center(
                        child: Text(tab.text),
              )),
              ).toList())

用到的是我們前面說到的map關鍵字,通過map我們將tab轉爲一個個的Center容器。然後直接將整個數組用來顯示。
controller
同TabBar的Controller,一般將他們的Controller用一個變量來設置,來統一行爲。
physics
控制tabBarView在滑動的操作,默認爲ScrollPhysics,如果想要修改滑動操作可以仿照該類進行重寫。
dragStartBehavior
拖動的滑動行爲,在默認滑動的時候默認值爲DragStartBehavior.start,自測的在修改爲DragStartBehavior.down後也沒有看到變化。

3.Image

Image可以是在我們日常使用中最頻繁的了,也給我們提供了多種顯示圖片的方法,我們可以根據需要來進行圖片的顯示。先看下最基礎的Image是需要我們如何做的:

 const Image({
    Key key,
    @required this.image,//需要自己實現的獲取圖片的方式。
    this.frameBuilder,//參照下面詳細解釋
    this.loadingBuilder,//參照下面詳細解釋
    this.semanticLabel,//關於圖片的描述,不重要
    this.excludeFromSemantics = false, //排除image的語義,True則會忽略semanticLabel的內容
    this.width,//設置顯示的寬度
    this.height,//設置顯示的高度,需要注意的是如果寬高小於圖片的寬高則會以最短邊爲基準等比例的裁剪,居中顯示,如果寬高大於圖片的寬高則圖片不拉伸居中顯示
    this.color, //設置圖片的前景色,圖片的主色會根據設定變化
    this.colorBlendMode,//圖片的混合模式,一般與color配合使用
    this.fit,//參照下面詳細解釋
    this.alignment = Alignment.center,//對齊方式,前面列舉了很多,不再贅述
    this.repeat = ImageRepeat.noRepeat,//參照下面詳細解釋
    this.centerSlice,//參照下面詳細解釋
    this.matchTextDirection = false,//參照下面詳細解釋
    this.gaplessPlayback = false,//圖片的路徑變化時是否保留顯示原圖片,True是保留,False則不會保留,重新加載的時候會空白一直等到圖片完全加載完
    this.filterQuality = FilterQuality.low,//圖片的質量控制
  })

frameBuilder
可以給Image添加邊框以及間距,也可以做出堆疊其他的控件的效果,列舉一個添加邊框的例子:

frameBuilder: (BuildContext context, Widget child, int frame,
                      bool wasSynchronouslyLoaded) {
                    return Padding(
                      padding: EdgeInsets.only(left: 5, top: 5),
                      child: child,
                    );
                  },

loadingBuilder
在圖片加載的時候,還沒有加載完成之前的顯示,當加載完成之後就會被image覆蓋掉。注意是覆蓋不是替換,如果加載的是一個透明或者半透的圖則會顯示出來loadingBuilder的組件。列舉一個簡單實用:

loadingBuilder: (BuildContext context, Widget child,
                      ImageChunkEvent loadingProgress) {
                    return Container(
                        color: Colors.yellow,
                        child: child);
                  },

fit
在如果寬高都大於圖片的時候可以通過fit屬性填充多出來的空間。
BoxFit.none 不設置
BoxFit.fill 寬高填滿,會引起圖片的拉伸
BoxFit.contain 以最大邊爲基準縮放圖片,完全顯示出圖片,會有空白
BoxFit.cover 以最小邊爲基準縮放圖片,填充滿圖片,會被裁切
BoxFit.fitWidth 圖片比例不變,寬填充滿,會有空白
BoxFit.fitHeight 圖片比例不變,高填充滿,會有空白
BoxFit.scaleDown 在不大於原圖尺寸的時候會等比例縮小,大於圖片尺寸則會原圖尺寸根據alignment設置
repeat
對於沒有填充滿的區域是否以原圖片重複添加的方式填充
ImageRepeat.repeat X軸和Y軸的空白空間都進行填充
ImageRepeat.repeatX X軸的空白空間進行填充
ImageRepeat.repeatY Y軸的空白空間進行填充
ImageRepeat.noRepeat 不進行填充
centerSlice
我們如果對一個圖片的局部進行拉伸,則可以通過該屬性進行設置,需要傳入一個Rect的對象,我們可以根據需要創建該實例,舉個簡單的例子:

centerSlice: Rect.fromLTRB(0,20,40,59),

用圖片的寬爲0-40,高爲20-59的部分進行圖片的拉伸,並填充滿整個image。
matchTextDirection
控制圖片的顯示方向是否跟文字的顯示方向一致,需要配合Directionality容器使用,Directionality容器可以控制子控件的顯示方向,如果設置爲false則不跟隨Directionality設置的方向顯示,True則會跟隨一樣顯示。舉個簡單例子:

 Directionality(
                textDirection: TextDirection.rtl,
                child: Image.network(
                  "https://img.jpg",
                  matchTextDirection: true,
                  ...})

上面剛剛介紹的是圖片的默認構造方法,這裏使用的時候我們還需要自己來寫一個加載方式,否則無法顯示出來圖片,但是Flutter已經幫我們創建了幾種加載方式,我們只需要根據場景選擇合適的加載方式即可。

方式一:

Image.asset()

在工程的根目錄下創建assets/images目錄,將要顯示的本地圖片放到該目錄下。
在根目錄下的pubspec.yaml文件中添加assets的引用:

flutter:
  uses-material-design: true
  assets:
    - assets/images/

這樣我們纔可以在程序中引用到該圖片。在使用中與基本的Image會有下面幾點不同:

Image.asset(
    String name, {
    AssetBundle bundle,//設定要讀取的資源Bundle,如果不設置則會從rootBundle裏獲取
    String package,//在取別的library的資源時候需要添加包名
    int cacheWidth,//指定的緩存的寬
    int cacheHeight,//指定的緩存的高
    ...
  })

方式二:

Image.network();

從網絡上獲取圖片,需要注意添加網絡權限,在android的manifest文件中添加:

    <uses-permission android:name="android.permission.INTERNET"/>

將圖片的地址直接傳入即可,其他參數與assets沒有區別。

方式三:

Image.file();

需要傳入一個File對象,File對象的需要我們導入IO包,import 'dart:io' show File;
File的創建也很簡單,我們只需要傳入文件的路徑即可創建成功。其他參數與assets沒有區別。

方式四:

Image.memory();

從內存中的bytes集合中獲取,將其傳入參數中進行顯示,其他參數與assets沒有區別。

基本上我們通過這兩篇的學習可以寫一個簡單的小demo跑起來了,還是需要多加練習,單看這些屬性有些無法理解的很透徹還是需要都實現一遍來看看效果的。

接下來我們學習Flutter基礎組件第三部分

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章